Greg,这真的是查询的全部内容吗?
示例表
create table A(rCode int, sid int);
insert A select 1,1;
insert A select 2,3;
insert A select 3,2;
insert A select 5,4;
insert A select 1,5;
create table B(rYear int, sid int);
insert B select 2011,1;
insert B select null,3;
insert B select 2011,2;
insert B select 2015,2;
查询:
SELECT * from A
left join B on A.sid = B.sid
where (rCode = 1 Or rCode = 2 Or rCode = 3 Or rCode = 5)
AND (rYear = 2011 or rYear is null);
SELECT * from A
left join B on A.sid = B.sid AND (rYear = 2011 or rYear is null)
where (rCode = 1 Or rCode = 2 Or rCode = 3 Or rCode = 5);
两个查询完全相同,都返回:
rCode sid rYear sid
----------- ----------- ----------- -----------
1 1 2011 1
2 3 NULL 3
3 2 2011 2
5 4 NULL NULL
1 5 NULL NULL
所以我很惊讶 Jage 的查询(第二个选项)对您有效,但对您的原始查询无效。如果没有内在的or rYear is null,情况就会不同。
这样想 LEFT JOIN [1]
SELECT * from A
left join B on A.sid = B.sid
将所有内容保留在 A 中,如果在 ON 子句中匹配,则保留 B,否则用 NULL 填充 B 列。添加 WHERE 子句 [2]
where (rCode = 1 Or rCode = 2 Or rCode = 3 Or rCode = 5)
AND (rYear = 2011 or rYear is null);
使用 [1] 的输出,根据过滤器进行 CUT,在左连接之后应用。使用rYear is null,它仍应保留所有 A 记录,条件是匹配 rCode 过滤器。但是,如果 rYear 中的过滤器只有
AND (rYear in (2011,2012))
这是一个不同的故事,因为在 B 不匹配的地方,rYear 用 NULL 填充,这与 rYear 过滤器不匹配 -> 整行被删除,包括 A 记录。 rYear 上的此类过滤器将进入 ON 子句,如下所示,否则不妨将其设为 INNER JOIN。
SELECT * from A
left join B on A.sid = B.sid AND (rYear in (2011,2012))
where (rCode = 1 Or rCode = 2 Or rCode = 3 Or rCode = 5)