在项目开发中,我们用的join一般有left join、right join和inner join。有时候会发现写在on后面的过滤条件有时候不生效。
问题
最近项目上反馈,角色类别表数据被删除,但是在角色树上仍然能够被查出来。查看接口代码,发现查询sql用的left join。
sql语句类似如下
select js.id as id, js.mc as jsmc,fl.id as flId, fl.mc as flmc
from JS_LB fl left join on JS js on fl.id = js.js_lb_id and fl.sfsc = 'N'
where js.sfsc = 'N' or js.sfsc is null
查看上面sql,发现有2个问题:
1、为啥fl.sfsc = 'N'怎么没生效?
2、为什么JS表过滤条件用到了or,这不是很影响性能?
原因
带着上面2个疑问,查了资料,发现
join类型 | 过滤条件是否生效 | 原因 |
A left join B on A.xx = B.xx1 and A.条件1 and B.条件2 where A.条件3 and B.条件4 | where后面条件都生效 A.条件1 不生效 B.条件2 生效 | left join是会返回A表的全量数据,对A表的过滤条件失败 |
A right join B on A.xx = B.xx1 and A.条件1 and B.条件2 where A.条件3 and B.条件4 | where后面条件都生效 A.条件1 生效 B.条件2 不生效 | right join是会返回B表的全量数据,对B表的过滤条件失败 |
A inner join B on A.xx = B.xx1 and A.条件1 and B.条件2 where A.条件3 and B.条件4 | where后面条件都生效 A.条件1 生效 B.条件2 生效 | inner join,是对A表进行条件过滤之后,再join B表进行条件过滤之后的数据 |
针对这2点。上面的sql,可以修改成,这样就只会查出角色分类表和角色表未删除数据,不影响性能
select js.id as id, js.mc as jsmc,fl.id as flId, fl.mc as flmc
from JS_LB fl left join on JS js on fl.id = js.js_lb_id and js.sfsc = 'N'
where fl.sfsc = 'N'