sql - 查询之间的区别
问题描述
我有三个表
TAB01
坎普1 | 坎普2 01 |一个 02 |二 03 |三 04 |四
TAB02
坎普1 | 坎普2 01 |一个 02 |二 03 |三
TAB03
坎普1 | 坎普2 01 |一个 02 |二 03 |三
当我执行查询时
SELECT TAB01.CAMPO1,TAB02.CAMPO2
FROM TAB01
LEFT JOIN TAB02 ON TAB02.CAMPO1=TAB01.CAMPO1
INNER JOIN TAB03 ON TAB03.CAMPO1=TAB02.CAMPO1
结果是
坎普1 | 坎普2 01|01 02|02 03|03
当我执行查询时
SELECT TAB01.CAMPO1,T1.CAMPO2
FROM TAB01
LEFT JOIN (SELECT TAB02.CAMPO1,TAB02.CAMPO2 FROM_TAB02
INNER JOIN TAB03 ON TAB03.CAMPO1=TAB02.CAMPO1) T1 ON T1.CAMPO1=TAB01.CAMPO1
结果是
坎普1 | 坎普2 01|01 02|02 03|03 04|空
为什么?
不应该一样吗?
解决方案
您的两个查询是:
SELECT TAB01.CAMPO1, TAB02.CAMPO2
FROM TAB01 LEFT JOIN
TAB02 ON
TAB02.CAMPO1 = TAB01.CAMPO1 INNER JOIN
TAB03
ON TAB03.CAMPO1 = TAB02.CAMPO1
SELECT TAB01.CAMPO1, T1.CAMPO2
FROM TAB01 LEFT JOIN
(SELECT TAB02.CAMPO1,TAB02.CAMPO2
FROM_TAB02 INNER JOIN
TAB03
ON TAB03.CAMPO1 = TAB02.CAMPO1
) T23 -- changed the alias to something more reasonable
ON T23.CAMPO1 = TAB01.CAMPO1
这些在结果集中的行方面完全不同。
对于第一个查询,逻辑是:
TAB01
即使 . 中没有匹配项,也要保留所有行TAB02
。- 然后最终结果集只有行 where
TAB02
和TAB03
match。 - 因为
NULL
s不匹配最终INNER JOIN
条件,所以查询本质上都是INNER JOIN
s。
第二个查询的逻辑是:
TAB01
即使 . 中没有匹配项,也要保留所有行T23
。- 加入
TAB02
,TAB03
因此只有匹配的行。
上没有额外的过滤TAB01
。
作为外部连接的一般规则,我建议:
INNER JOIN
如果有的话,首先使用s。这些可以过滤数据。- 然后使用
LEFT JOIN
s 保留前面一个或多个表中的所有行。 - 一旦使用
LEFT JOIN
,请勿使用INNER JOIN
或RIGHT JOIN
。
FULL JOIN
s 很少需要。而且我几乎从不使用RIGHT JOIN
s。
推荐阅读
- azure-log-analytics - KQL:查询除现有列之外的动态列中的所有变量
- r - 如何在 xpath/R 中找到所有没有子节点的节点(从非根节点开始!)?
- string - 列出带有字符串的文件,然后使用 powershell 检查所有文件
- php - 在类中调用全局变量
- php - reactjs php提交表单后如何加载表格数据
- angular - 在 Angular 8 的 jsPDF 中添加来自另一个域的图像的 CORS 错误
- java - Reactor WebFlux:帮助理解如何工作 flatMap()
- qt - 为信号增加价值
- jasper-reports - Jaspersoft/Jasperreports:如何将参数列表传递给 IN 子句?
- discord.py - Discord.py 如何下载服务器图标?