在SQL中,我尝试根据ID过滤结果,不知道
SELECT value
FROM table1
JOIN table2 ON table1.id = table2.id
WHERE table1.id = 1
和
SELECT value
FROM table1
JOIN table2 ON table1.id = table2.id AND table1.id = 1
对我来说,逻辑似乎是不同的,尽管你总是得到相同的结果集,但我想知道在什么情况下你会得到两个不同的结果集(或者它们总是返回完全相同的两个结果集)
发布于 2015-12-24 23:28:26
答案是没有区别,但是:
我总是更喜欢做下面的事情。
ON
子句中where
子句这使得查询的更具可读性。
所以我将使用这个查询:
SELECT value
FROM table1
INNER JOIN table2
ON table1.id = table2.id
WHERE table1.id = 1
但是,当您使用OUTER JOIN'S
时,将过滤器保留在ON
条件和Where
条件中有很大的不同。
逻辑查询处理
以下列表包含查询的一般形式,以及根据不同子句在逻辑上处理的顺序分配的步骤编号。
(5) SELECT (5-2) DISTINCT (5-3) TOP(<top_specification>) (5-1) <select_list>
(1) FROM (1-J) <left_table> <join_type> JOIN <right_table> ON <on_predicate>
| (1-A) <left_table> <apply_type> APPLY <right_table_expression> AS <alias>
| (1-P) <left_table> PIVOT(<pivot_specification>) AS <alias>
| (1-U) <left_table> UNPIVOT(<unpivot_specification>) AS <alias>
(2) WHERE <where_predicate>
(3) GROUP BY <group_by_specification>
(4) HAVING <having_predicate>
(6) ORDER BY <order_by_list>;
流程图逻辑查询处理
发布于 2015-12-24 23:48:03
虽然使用内部联接没有区别,但正如VR46所指出的,在使用外部联接和评估第二个表中的值(对于左联接-第一个表对于右联接)时,有一个显著的区别。考虑以下设置:
DECLARE @Table1 TABLE ([ID] int)
DECLARE @Table2 TABLE ([Table1ID] int, [Value] varchar(50))
INSERT INTO @Table1
VALUES
(1),
(2),
(3)
INSERT INTO @Table2
VALUES
(1, 'test'),
(1, 'hello'),
(2, 'goodbye')
如果我们使用左外部联接从其中进行选择,并在where子句中添加一个条件:
SELECT * FROM @Table1 T1
LEFT OUTER JOIN @Table2 T2
ON T1.ID = T2.Table1ID
WHERE T2.Table1ID = 1
我们得到了以下结果:
ID Table1ID Value
----------- ----------- --------------------------------------------------
1 1 test
1 1 hello
这是因为where子句限制了结果集,所以我们只包含table1中ID为1的记录。但是,如果我们将条件移到on子句:
SELECT * FROM @Table1 T1
LEFT OUTER JOIN @Table2 T2
ON T1.ID = T2.Table1ID
AND T2.Table1ID = 1
我们得到了以下结果:
ID Table1ID Value
----------- ----------- --------------------------------------------------
1 1 test
1 1 hello
2 NULL NULL
3 NULL NULL
这是因为我们不再通过表1的ID 1过滤结果集,而是过滤连接。因此,即使Table1的ID 2在第二个表中有匹配,它也会被排除在连接之外,而不是结果集(因此是NULL值)。
因此,对于内部连接,这并不重要,但为了可读性和一致性,您应该将其保留在where子句中。但是,对于外连接,您需要知道将条件放在何处确实很重要,因为它将影响您的结果集。
发布于 2017-01-16 20:18:16
我认为被标记为“正确”的答案是不正确的。为什么?我试着解释:
我们有自己的看法
“始终保留ON子句中的联接条件始终将筛选器的条件放在where子句中”
这是错误的。如果您是在inner中,则每次都将过滤器参数放在ON子句中,而不是where中。你问为什么?试着想象一下总共有10个表的复杂查询(F.E.每个表都有10k个recs)连接,带有复杂的WHERE子句(例如,使用的函数或计算)。如果将筛选条件放在ON子句中,这10个表之间的连接将不会发生,WHERE子句将根本不会执行。在这种情况下,您没有在WHERE子句中执行10000^10计算。这是有意义的,不仅仅是将过滤参数放在WHERE子句中。
https://stackoverflow.com/questions/34454867
复制相似问题