MySQL Left Join 不返回连接表的空值
请帮助我执行以下 MySQL 查询,该查询连接两个表(A 和 B):
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)
roleCode
是表 A 中的字段,rYear
是表 B 中的字段
结果设置不符合预期。仅返回 185 行,但表 A 中有 629 行符合 where 条件。表 B 中没有匹配行的行不应该返回其 B 字段的空值吗?
Please help me with the following MySQL query, which joins two tables (A and B):
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)
roleCode
is a field in table A and rYear
is a field in table B
The result set is not as expected. Only 185 rows are returned, but there are 629 rows in table A that match the where condition. Shouldn't the rows without a matching row in table B be returned with null values for their B fields?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不应在 WHERE 子句中指定 rYear。这些限制了您加入后的结果。您应该在 ON 子句中指定 rYear 以从表 B 中获取 NULL 记录。
You should not specify rYear in a WHERE clause. Those limit your results after the join. You should specify rYear in an ON clause to get back records with NULL from table B.
格雷格,这真的是查询的全部内容吗?
示例表
查询:
这两个查询完全相同,都返回:
所以我很惊讶 Jage 的查询(第二个选项)适合您,但不适用于您的原始查询。如果没有内部
或 rYear 为 null
,情况将会有所不同。将 LEFT JOIN 想象成这样 [1]
将所有内容保留在 A 中,并且在 ON 子句中匹配的情况下,保留 B,否则用 NULL 填充 B 列。添加 WHERE 子句 [2]
使用 [1] 的输出,根据过滤器进行削减,在左连接之后应用。当 rYear 为 null 时,它仍应保留所有 A 记录,前提是 rCode 过滤器匹配。但是,如果 rYear 中的过滤器只是 则
另当别论,因为在 B 不匹配的地方,rYear 被填充了 NULL,这将与 rYear 过滤器不匹配 ->整行都会被删除,包括 A 记录。 rYear 上的此类过滤器将进入 ON 子句,如下所示,否则也可能使其成为 INNER JOIN。
Greg, is that really all there is to the query?
Sample tables
Queries:
Both of the queries are exactly the same, both returning:
So I am surprised that Jage's query (the 2nd option) works for you but not your original. It would be different story without the inner
or rYear is null
.Think of the LEFT JOIN like this [1]
Keep everything in A, and where matched in the ON clause, keep B otherwise pad B columns with NULL. Add the WHERE clause [2]
Using the output from [1], CUT down based on the filter, applied AFTER the left join. With the
rYear is null
, it should still keep all A records, on the proviso that the rCode filter is matched. However, if the filter in rYear is onlyIt's a different story, because where B was not matched, the rYear was padded with NULL, which won't match the rYear filter -> the entire row gets removed, including the A record. Such a filter on rYear would have gone into the ON clause as shown below, otherwise might as well make it an INNER JOIN.