在阅读它之后,这不是显式与隐式SQL连接的副本。 答案可能相关(甚至相同),但问题是不同的。
它们之间有什么不同?每一种都应该有什么不同?
如果我正确地理解了这个理论,那么查询优化器应该能够互换地使用这两种方法。
在阅读它之后,这不是显式与隐式SQL连接的副本。 答案可能相关(甚至相同),但问题是不同的。
它们之间有什么不同?每一种都应该有什么不同?
如果我正确地理解了这个理论,那么查询优化器应该能够互换地使用这两种方法。
当前回答
在SQL中,'WHERE'和'ON'子句是一种条件语句,但它们之间的主要区别是,'WHERE'子句用于选择/更新语句中指定条件,而'ON'子句用于连接,在连接表之前,它验证或检查目标表和源表中的记录是否匹配
例如:“WHERE”
SELECT * FROM employee WHERE employee_id=101
例如:- 'ON'
有两个表employee和employee_details,对应的列为employee_id。
SELECT * FROM employee
INNER JOIN employee_details
ON employee.employee_id = employee_details.employee_id
希望我已经回答了你的问题。 回复以获得任何澄清。
其他回答
它们不是一回事。
考虑一下这些问题:
SELECT *
FROM Orders
LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID
WHERE Orders.ID = 12345
and
SELECT *
FROM Orders
LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID
AND Orders.ID = 12345
第一个将返回订单及其行(如果有的话),订单号为12345。 第二个将返回所有订单,但只有订单12345有与之关联的行。
使用INNER JOIN,这两个子句实际上是等效的。然而,仅仅因为它们在功能上相同,产生相同的结果,并不意味着这两种子句具有相同的语义。
在INNER join中,它们是可互换的,优化器会随意重新排列它们。
在OUTER连接上,它们不一定是可互换的,这取决于它们所依赖的连接的哪一侧。
我把它们放在任意一个位置,取决于可读性。
内连接不重要吗 外部连接的注意事项 a. WHERE从句:加入后。在连接发生后,将过滤记录。 b. ON条款-加入前。记录(来自右表)将在加入之前被过滤。这可能在结果中以null结束(因为OUTER连接)。
示例:考虑以下表格:
文档: id 的名字 1 Document1 2 Document2 3. Document3 4 Document4 5 Document5 下载: id document_id 用户名 1 1 sandeep 2 1 思米 3. 2 sandeep 4 2 •拉赫曼 5 3. 思米
a) WHERE从句内:
SELECT documents.name, downloads.id
FROM documents
LEFT OUTER JOIN downloads
ON documents.id = downloads.document_id
WHERE username = 'sandeep'
对于上述查询,中间连接表将如下所示。
id(from documents) | name | id (from downloads) | document_id | username |
---|---|---|---|---|
1 | Document1 | 1 | 1 | sandeep |
1 | Document1 | 2 | 1 | simi |
2 | Document2 | 3 | 2 | sandeep |
2 | Document2 | 4 | 2 | reya |
3 | Document3 | 5 | 3 | simi |
4 | Document4 | NULL | NULL | NULL |
5 | Document5 | 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(from documents) | name | id (from 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 |
注意文档中不符合这两个条件的行是如何用NULL值填充的。
选择列出的属性后,结果将是:
name | id |
---|---|
Document1 | 1 |
Document2 | 3 |
Document3 | NULL |
Document4 | NULL |
Document5 | NULL |
我认为这种区别可以通过SQL中操作的逻辑顺序来最好地解释,这是简化的:
FROM(包括连接) 在哪里 集团 聚合 有 窗口 选择 截然不同的 并,相交,除 命令 抵消 获取
联接不是select语句的子句,而是FROM语句中的操作符。因此,当逻辑处理到达WHERE子句时,属于相应JOIN运算符的所有ON子句在逻辑上“已经发生”。这意味着在LEFT JOIN的情况下,例如,在应用WHERE子句时,外部连接的语义已经发生。
我已经在这篇博文中更深入地解释了下面的例子。运行此查询时:
SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
WHERE film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;
LEFT JOIN实际上没有任何有用的效果,因为即使演员没有在电影中演出,演员也会被过滤,因为它的FILM_ID将为NULL, WHERE子句将过滤这样的一行。结果是这样的:
ACTOR_ID FIRST_NAME LAST_NAME COUNT
--------------------------------------
194 MERYL ALLEN 1
198 MARY KEITEL 1
30 SANDRA PECK 1
85 MINNIE ZELLWEGER 1
123 JULIANNE DENCH 1
也就是说,就好像我们内部连接了两个表。如果我们移动ON子句中的筛选谓词,它现在成为外部连接的标准:
SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
AND film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;
这意味着结果将包含没有任何影片的演员,或者没有任何影片且FILM_ID < 10的演员
ACTOR_ID FIRST_NAME LAST_NAME COUNT
-----------------------------------------
3 ED CHASE 0
4 JENNIFER DAVIS 0
5 JOHNNY LOLLOBRIGIDA 0
6 BETTE NICHOLSON 0
...
1 PENELOPE GUINESS 1
200 THORA TEMPLE 1
2 NICK WAHLBERG 1
198 MARY KEITEL 1
简而言之
总是把谓词放在逻辑上最有意义的地方。
通常,一旦两个表已经连接,就在WHERE子句中处理筛选。这是有可能的,不过您可能希望在连接它们之前过滤一个或两个表。 也就是说,where子句适用于整个结果集,而on子句只适用于相关的连接。