昨天在工作的时候遇到如下的情况
现在有2张表
user | doctor_team_member |
id |
id |
name |
team_id |
hospital_id |
hospital_id |
delete_flg |
delete_flg |
doctor_id |
user表存的是所有的医生用户,doctor_team_member 存的是 所有医院里面已经编入了团队的医生。现在需要查询出某个医院下面所有没有加入任何团队的医生。
1.0 版本 是这样的:
SELECT * FROM user u LEFT JOIN doctor_team_members dtm ON u.id = dtm.doctor_id WHERE dtm.team_id IS NULL AND u.hospital_id = 73603893786841088;
这就是忽略了delete_flg=1 被逻辑删除的用户 。当有个用户被逻辑删除的时候,但在筛选的时候,筛选不出被逻辑删除的用户。因为被逻辑删除的用户在 doctor_team_members 表中是有数据的可以和user.id 关联上。
然后就是2.0版本:
SELECT * FROM user u LEFT JOIN
doctor_team_members dtm ON u.id = dtm.doctor_id WHERE (dtm.team_id IS NULL OR dtm.delete_flg ='1') AND u.hospital_id = 73603893786841088;
这样就可以把被逻辑删除的用户再筛选出来。 但现在又出现了新的问题,假如我们新增一个 doctor_team_members数据后。再把他逻辑删除掉,然后我们再新增同一个医生加入 doctor_team_members 。现在数据库里面,有一个逻辑删除的医生和一个同名同id 的新加的医生。这个时候问题就出现了,我们再次查询的时候,那个医生就会出现在该医院下未加入任何团队的名单里面。当我们再逻辑删除他的时候再查询,还有出现多个同名医生的情况。那些多出来的医生就是 delete_flg='1'的医生且同一个的医生。
然后就是最终解决方案。完全排除 delete_flg='1' 的医生
SELECT * FROM action_user u LEFT JOIN
doctor_team_members dtm ON u.id = dtm.doctor_id AND dtm.delete_flg ='0' WHERE dtm.team_id IS NULL
AND u.delete_flg = '0'
AND u.hospital_id = 73603893786841088;
在关联表的时候就把 delete_flg ='1' 的数据去掉,然后再执行 where 的条件进行筛选。这样就不用受 delete_flg='1'的影响了。
总结:
- 在有逻辑删除的表里面,增删改查的时候,首先把 逻辑删除的 字段 排除掉,然后再做操作。有join 的
就放在 on 的条件里面,先on 再 where 。 (忽视了on 和 where 的执行顺序让我脑壳疼了很久)