将过滤条件放在 join on 语句中是不是等效? [复制]
Posted
技术标签:
【中文标题】将过滤条件放在 join on 语句中是不是等效? [复制]【英文标题】:Is placing the filter condition inside the join on statement equivalent? [duplicate]将过滤条件放在 join on 语句中是否等效? [复制] 【发布时间】:2019-02-12 12:10:08 【问题描述】:我一直假设以下形式的陈述
SELECT * FROM A LEFT JOIN B ON (A.column1 = B.column2 AND B.column2 = 12321)
总是等价于
SELECT * FROM A LEFT JOIN B ON (A.column1 = B.column2)
WHERE B.column2 = 12321
更笼统地说:
SELECT * FROM A LEFT JOIN B ON (FOREIGN-KEY AND FILTER_ON(B))
WHERE FILTER_ON(A)
应该等价于
SELECT * FROM A LEFT JOIN B ON (FOREIGN-KEY)
WHERE FILTER_ON(A) AND FILTER_ON(B)
情况似乎并非如此...第一种类型提供的结果行数比第二种类型多。
问题:在哪些情况下我的假设是错误的?
【问题讨论】:
学习 SQL 的最佳方式是编程。创建表,插入一些数据,看看是否有区别! (提示:有。将右侧表条件放在 ON 子句中,否则会得到常规的内连接结果。) 最好的理解方式是:在查询中只显示匹配where条件的记录——反之,如果左连接条件不匹配,则显示记录,但是左连接表有一个空行...(如果您使用普通连接(没有左连接),那么这两个语句是等价的,但对于左连接、右连接或全连接不适用。) @jarlh 我不认为这个问题值得 go-and-learn-sql-first 评论。 Mathtec,欢迎加入! 【参考方案1】:没有。对于外连接,它们是不等价的。
left join
将 所有 行保留在第一个表中,无论 on
子句的计算结果是 true、false 还是 NULL
。因此,on
中的条件仅对 first 表无效。
如果您想过滤left join
中的first 表,请将条件放入where
。第二张表的条件一般放在on
子句中。
【讨论】:
非常感谢您的回复!我已经更新了问题,但我仍然不明白为什么第二个表 B 上的过滤条件对连接条件中的结果有不同的影响。【参考方案2】:在您的第一个查询中,您编写了LEFT JOIN
,这意味着左侧表格中的所有数据。
查询:1 SELECT * FROM A LEFT JOIN B ON (FOREIGN-KEY AND FILTER_ON(A) AND FILTER_ON(B))
查询:2 SELECT * FROM A LEFT JOIN B ON (FOREIGN-KEY)
WHERE FILTER_ON(A) AND FILTER_ON(B)
在 Query:1 中,在LEFT JOIN
中有条件,这意味着当条件变为 false 时,我们仍然有左侧表中的所有数据和 NULL
值和 Table B
。
如果您在where
子句(Query:2) 中为table B
编写条件,则查询1 和查询2 的结果将出现数据不匹配。因为数据将在查询结果中按条件过滤掉。
【讨论】:
以上是关于将过滤条件放在 join on 语句中是不是等效? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
SQL 查询条件放在LEFT OUTER JOIN 的ON语句后与放在WHERE中的区别
SQL语句中 LEFT JOIN 后 ON 和 WHERE 的区别
SQL语句中 LEFT JOIN 后 ON 和 WHERE 的区别