我想将* =的SQL语法转换为LEFT OUTER JOIN。这是原始语法:
选择 a.col1, a.col2, b.col1, b.col2, b.col3, b.col4从 tableA AS a, tableB …
一 LEFT JOIN 足够。你能试试吗?
LEFT JOIN
SELECT a.col1, a.col2, b.col1, b.col2, b.col3, b.col4 FROM tableA AS a LEFT OUTER JOIN tableB AS b ON a.col1 = b.col1 AND a.col2 = b.col2 WHERE b.col3 = "xxx" AND b.col4 = "yyy"
您可以使用 AND 在里面 JOIN 句法:
AND
JOIN
SELECT a.col1, a.col2, b.col1, b.col2, b.col3, b.col4 FROM tableA AS a LEFT OUTER JOIN tableB AS b ON a.col1 = b.col1 AND a.col2 = b.col2 WHERE b.col3 = "xxx" b.col4 = "yyy"
您的第一个查询仅涉及 一 左边连接两个表,因为所有的 *= 涉及同一对别名的比较用于一个左连接。所以我们将它们合二为一 left join 的 on 。
*=
left join
on
当只有一对桌子连在一起时 from ,一个非列的比较 * table到常量也是左连接标准的一部分。所以它也进入了 on :
from
*
在左连接中,外表和内表是左表和右表 分别。
如果您从外部联接的内部表中提交具有外部联接和列的限定条件的查询,则结果可能与您的预期不符。查询中的限定不限制返回的行数,而是影响哪些行包含空值。对于不符合限定条件的行,空值将显示在这些行的内部表的列中。
这给出了:
SELECT a.col1, a.col2, b.col1, b.col2, b.col3, b.col4 FROM tableA AS a LEFT OUTER JOIN tableB AS b ON a.col1 = b.col1 AND a.col2 = b.col2 AND b.col3 = "xxx" ??? b.col4 = "yyy"
对于完整的语义,请参阅 Transact-SQL®AdaptiveServer®Enterprise15.7用户指南 。特别是 * 从版本12.0开始,某些多连接查询的左连接语义已更改。
笔记:
left (outer) join
出于讨论目的,我将创建一些表和一些示例数据:
use tempdb go if object_id('tableA') is not NULL drop table tableA go if object_id('tableB') is not NULL drop table tableB go create table tableA (col1 int ,col2 int ) go insert tableA values (1,1) insert tableA values (1,2) insert tableA values (2,3) insert tableA values (2,4) go create table tableB (col1 int ,col2 int ,col3 varchar(10) null ,col4 varchar(10) null ) go insert tableB values (1,1,'xxx','yyy') insert tableB values (1,2,null,null) go
用旧式写外连接(即 *= 和 =* ),所有 where 在连接操作期间应用了子句,给出了以下结果:
=*
where
select a.col1, a.col2, b.col1, b.col2, b.col3, b.col4 from tableA AS a, tableB AS b where a.col1 *= b.col1 and a.col2 *= b.col2 and b.col3 = "xxx" and b.col4 = "yyy" go col1 col2 col1 col2 col3 col4 ----------- ----------- ----------- ----------- ---------- ---------- 1 1 1 1 xxx yyy 1 2 NULL NULL NULL NULL 2 3 NULL NULL NULL NULL 2 4 NULL NULL NULL NULL
而第一个 tableA 记录根据a)2搜索参数(SARG)子句(col3 = xxx,col4 = yyy)和b)连接子句...其他3找到匹配 tableA 记录找不到匹配(主要是由于2个SARG条款没有匹配)所以 的 所有 强> tableB 列用NULL填充。
tableA
tableB
我们可以使用以下内容生成相同的结果集 left (outer) join 样式查询:
select a.col1, a.col2, b.col1, b.col2, b.col3, b.col4 from tableA as a left join tableB as b on a.col1 = b.col1 and a.col2 = b.col2 and b.col3 = "xxx" and b.col4 = "yyy" go col1 col2 col1 col2 col3 col4 ----------- ----------- ----------- ----------- ---------- ---------- 1 1 1 1 xxx yyy 1 2 NULL NULL NULL NULL 2 3 NULL NULL NULL NULL 2 4 NULL NULL NULL NULL
同样,SARG条款作为联接操作的一部分应用。
现在,如果目标是应用SARG条款 的 后 强> 加入操作已经完成,我们需要将SARG分开 where 条款;要看看它是如何工作的,我们首先只使用join子句运行查询(即删除SARG子句):
select a.col1, a.col2, b.col1, b.col2, b.col3, b.col4 from tableA as a left join tableB as b on a.col1 = b.col1 and a.col2 = b.col2 go col1 col2 col1 col2 col3 col4 ----------- ----------- ----------- ----------- ---------- ---------- 1 1 1 1 xxx yyy 1 2 1 2 NULL NULL 2 3 NULL NULL NULL NULL 2 4 NULL NULL NULL NULL
将SARG条款作为单独的条款应用 where 我们现在只能过滤掉我们想要的行(即col3 = xxx和col4 = yyy),如下所示:
select a.col1, a.col2, b.col1, b.col2, b.col3, b.col4 from tableA as a left join tableB as b on a.col1 = b.col1 and a.col2 = b.col2 -- apply the SARGs **after** the join: where b.col3 = "xxx" and b.col4 = "yyy" go col1 col2 col1 col2 col3 col4 ----------- ----------- ----------- ----------- ---------- ---------- 1 1 1 1 xxx yyy
所以,在这一点上,我们可以看到有几个不同的结果集可以从中生成 left (outer) join 查询的样式...结果是'正确'将取决于你试图生成的最终结果...这回到关于提供一个的评论 最小,完整和可验证的例子
请尝试以下示例代码