SQL连接 - WHERE子句 vs. ON子句
SQL连接 - WHERE子句 vs. ON子句
阅读后,这不是重复的 Explicit vs Implicit SQL Joins。
答案可能相关(甚至相同),但问题不同。
区别是什么,每个应该放什么?
如果我理解正确,查询优化器应该能够互换使用。
admin 更改状态以发布 2023年5月20日
-
对于内部连接没有影响
-
对于外部连接有影响
a.
WHERE
子句:连接之后过滤。记录将在连接完成后进行过滤。b.
ON
子句 -连接之前。记录(来自右表)将在连接之前进行过滤。这可能会在结果中变为空(因为是外连接)。
示例:考虑以下表:
-
documents:
id name 1 Document1 2 Document2 3 Document3 4 Document4 5 Document5 -
downloads:
id document_id username 1 1 sandeep 2 1 simi 3 2 sandeep 4 2 reya 5 3 simi
a)在WHERE
子句中:
SELECT documents.name, downloads.id FROM documents LEFT OUTER JOIN downloads ON documents.id = downloads.document_id WHERE username = 'sandeep'
对于以上查询,中间的连接表将如下所示。
文档ID | 名称 | 下载ID | 文档ID | 用户名 |
---|---|---|---|---|
1 | 文档1 | 1 | 1 | Sandeep |
1 | 文档1 | 2 | 1 | Simi |
2 | 文档2 | 3 | 2 | Sandeep |
2 | 文档2 | 4 | 2 | Reya |
3 | 文档3 | 5 | 3 | Simi |
4 | 文档4 | NULL | NULL | NULL |
5 | 文档5 | NULL | NULL | NULL |
应用WHERE
子句并选择所列出的属性后,结果将如下所示:
name | id |
---|---|
Document1 | 1 |
Document2 | 3 |
b) 在JOIN
子句中
SELECT documents.name, downloads.id FROM documents LEFT OUTER JOIN downloads ON documents.id = downloads.document_id AND username = 'sandeep'
对于上面的查询,中间的连接表看起来像这样。
id(来自documents) | name | id(来自downloads) | document_id | username |
---|---|---|---|---|
1 | Document1 | 1 | 1 | sandeep |
2 | Document2 | 3 | 2 | sandeep |
3 | Document3 | NULL | NULL | NULL |
4 | Document4 | NULL | NULL | NULL |
5 | Document5 | NULL | NULL | NULL |
注意,documents
中未满足两个条件的行填充有NULL
值。
在选择列出的属性之后,结果如下:
name | id |
---|---|
Document1 | 1 |
Document2 | 3 |
Document3 | NULL |
Document4 | NULL |
Document5 | NULL |
它们并不是同一个东西。
考虑这些查询:
SELECT * FROM Orders LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID WHERE Orders.ID = 12345
和
SELECT * FROM Orders LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID AND Orders.ID = 12345
第一个查询将返回订单及其行(如果有)的信息,订单号为12345
。
第二个查询将返回所有订单,但只有订单12345
会有任何相关的行。
使用INNER JOIN
,这些语句在实际上是等价的。然而,它们能产生相同的结果,并不意味着这两种语句具有相同的语义含义。