You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

LEFT JOIN返回NULL值求助:AND过滤条件未按预期排除无效数据

解决LEFT JOIN后出现未过滤NULL的问题

嘿,这个问题太典型了——核心是你搞混了LEFT JOIN的ON条件和WHERE条件的作用差异

先帮你理清楚为什么会出现这种情况:LEFT JOIN的核心逻辑是强制保留左表的所有行,哪怕右表找不到符合ON条件的匹配记录,这时候右表的字段就会返回NULL。你第二个LEFT JOIN里的P.POSITION IN (3, 4, 5)(注:你写的PR.POSITION应该是笔误,正确表别名是P)只是在关联PERSON表时筛选匹配项,当没有符合条件的PERSON记录时,并不会过滤掉CASE和ATTENDANCE的行,而是把P.NAME等字段设为NULL返回,这就是你看到的“本该过滤却返回NULL”的原因。

接下来给你两种解决方案,你可以根据实际需求来选:

方案1:只保留有符合条件PERSON的记录(转成INNER JOIN)

如果你的需求是必须同时存在符合角色的ATTENDANCE和符合职位的PERSON,那直接把第二个LEFT JOIN改成INNER JOIN就行,这样只有匹配到符合条件的PERSON时才会返回该行:

SELECT C.CASE_ID, A.PERSON_ID, P.NAME 
FROM CASE C 
LEFT JOIN ATTENDANCE A ON C.CASE_ID = A.CASE_ID AND A.ROLE IN (1, 2) 
INNER JOIN PERSON P ON A.PERSON_ID = P.PERSON_ID AND P.POSITION IN (3, 4, 5)

方案2:保留ATTENDANCE行,但过滤掉PERSON不符合条件的记录

如果需要保留所有符合角色的ATTENDANCE行,但只显示那些有符合职位PERSON的记录(过滤掉PERSON为NULL的行),就把POSITION的条件移到WHERE子句里:

SELECT C.CASE_ID, A.PERSON_ID, P.NAME 
FROM CASE C 
LEFT JOIN ATTENDANCE A ON C.CASE_ID = A.CASE_ID AND A.ROLE IN (1, 2) 
LEFT JOIN PERSON P ON A.PERSON_ID = P.PERSON_ID 
WHERE P.POSITION IN (3, 4, 5)

(注:这个写法和方案1的最终效果类似,但逻辑上是先完成LEFT JOIN再做过滤)

额外提示

如果你的需求是保留所有CASE行,即使没有ATTENDANCE或符合条件的PERSON,但只在PERSON符合职位时显示其名称,否则显示NULL,那你原来的写法是正确的——只要修正PR.POSITION的笔误就行:

SELECT C.CASE_ID, A.PERSON_ID, P.NAME 
FROM CASE C 
LEFT JOIN ATTENDANCE A ON C.CASE_ID = A.CASE_ID AND A.ROLE IN (1, 2) 
LEFT JOIN PERSON P ON A.PERSON_ID = P.PERSON_ID AND P.POSITION IN (3, 4, 5)

内容的提问来源于stack exchange,提问作者benilapit

火山引擎 最新活动