Ari*_*ian 4 sql t-sql sql-server left-join sql-server-2008
我有这个问题:
SELECT Q_ID,
Q_DESC,
COUNT(Q_ID)
FROM #tmp_rep
LEFT OUTER JOIN po_Questions po
ON Q_ID = Certificate AND FUNCS = 1
AND LEN(LTRIM(RTRIM(po.UserName))) > 0
AND LEN(LTRIM(RTRIM(po.UserNumber))) > 0
GROUP BY
Q_ID,
Q_DESC
ORDER BY
Q_ID
Run Code Online (Sandbox Code Playgroud)
表#tmp_rep有2列(Q_ID,Q_Desc)和4 行.表po_Questions有10个在证书行列中使用3个Q_ID代码.如果我运行此查询,那么每件事情都可以,对于Q-ID = 4,我得到0表示计数,但如果我以这种方式编写该查询:
SELECT Q_ID,
Q_DESC,
COUNT(Q_ID)
FROM #tmp_rep
LEFT OUTER JOIN po_Questions po
ON Q_ID = Certificate
WHERE FUNCS = 1
AND LEN(LTRIM(RTRIM(po.UserName))) > 0
AND LEN(LTRIM(RTRIM(po.UserNumber))) > 0
GROUP BY
Q_ID,
Q_DESC
ORDER BY
Q_ID
Run Code Online (Sandbox Code Playgroud)
然后我在结果中只获得3行,而Q_ID = 4不属于结果.为什么SQL Server有这种行为?
谢谢
对于非匹配的行po.UserName会NULL如此LEN(LTRIM(RTRIM(po.UserName)))是NULL
NULL > 0当谓词出现在你正在将你的外部联接转回内部联接时,评估结果UNKNOWN不是TRUE这样WHERE.类似于FUNCSSQLMenace指出的那样.
您可能想要下载Itzik Ben Gan的逻辑查询处理海报.
从概念上讲,会发生以下情况(但不应将其与物理实现的方式混淆!)
对于您的第一个查询:
#tmp_rep,po_QuestionsON Filter应用有效地执行INNER JOIN打开Q_ID = Certificate但也排除po_Questions与谓词不匹配的任何行.OuterRows from #tmp_rep添加回来.这些将包含NULL所有列 po_QuestionsWHERE条款,所以这是最终的结果.对于您的第二个查询:
#tmp_rep,po_QuestionsON Filter应用有效地INNER JOIN开启Q_ID = Certificate.OuterRows from #tmp_rep添加回来.这些将包含NULL所有列 po_QuestionsWHERE评估该子句.这肯定会删除上一步中的所有行,也可能删除其他行.| 归档时间: |
|
| 查看次数: |
947 次 |
| 最近记录: |