war*_*ong 29 sql join resultset where
在SQL中,我试图根据ID过滤结果,并想知道它们之间是否存在任何逻辑差异
SELECT value
FROM table1
JOIN table2 ON table1.id = table2.id
WHERE table1.id = 1
Run Code Online (Sandbox Code Playgroud)
和
SELECT value
FROM table1
JOIN table2 ON table1.id = table2.id AND table1.id = 1
Run Code Online (Sandbox Code Playgroud)
对我来说,它好像逻辑是不同的,虽然你总是会得到相同的结果集,但我不知道是否有下,你会得到两个不同的结果集(或将它们总是返回完全相同的两个结果集的任何条件)
Pரத*_*ீப் 40
答案没有区别,但是:
我总是喜欢这样做.
ON子句where子句中这使查询更具可读性.
所以我将使用此查询:
SELECT value
FROM table1
INNER JOIN table2
ON table1.id = table2.id
WHERE table1.id = 1
Run Code Online (Sandbox Code Playgroud)
但是,当您使用时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>;
Run Code Online (Sandbox Code Playgroud)
流程图逻辑查询处理
(1)FROM:FROM阶段标识查询的源表和进程表运算符.每个表运算符都应用一系列子阶段.例如,连接中涉及的阶段是(1-J1)笛卡尔积,(1-J2)ON滤波器,(1-J3)添加外行.FROM阶段生成虚拟表VT1.
(1-J1)笛卡尔积:此阶段在表运算符中涉及的两个表之间执行笛卡尔积(交叉连接),生成VT1-J1.
它是从这个优秀的链接中提到的.
Sta*_*haw 13
虽然使用INNER JOINS没有区别,正如VR46指出的那样,当使用OUTER JOINS并评估第二个表中的值时(对于左连接 - 右连接的第一个表),存在显着差异.请考虑以下设置:
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')
Run Code Online (Sandbox Code Playgroud)
如果我们使用左外连接从中选择并在where子句中放入一个条件:
SELECT * FROM @Table1 T1
LEFT OUTER JOIN @Table2 T2
ON T1.ID = T2.Table1ID
WHERE T2.Table1ID = 1
Run Code Online (Sandbox Code Playgroud)
我们得到以下结果:
ID Table1ID Value
----------- ----------- --------------------------------------------------
1 1 test
1 1 hello
Run Code Online (Sandbox Code Playgroud)
这是因为where子句限制了结果集,因此我们只包含table1中ID为1的记录.但是,如果我们将条件移动到on子句:
SELECT * FROM @Table1 T1
LEFT OUTER JOIN @Table2 T2
ON T1.ID = T2.Table1ID
AND T2.Table1ID = 1
Run Code Online (Sandbox Code Playgroud)
我们得到以下结果:
ID Table1ID Value
----------- ----------- --------------------------------------------------
1 1 test
1 1 hello
2 NULL NULL
3 NULL NULL
Run Code Online (Sandbox Code Playgroud)
这是因为我们不再通过table1的ID为1过滤结果集 - 而是我们正在过滤JOIN.因此,即使table1的ID为2 DOES在第二个表中有匹配,它也会从连接中排除 - 但不是结果集(因此为空值).
因此,对于内部联接并不重要,但是为了可读性和一致性,您应该将它保留在where子句中.但是,对于外连接,您需要注意,放置条件的位置很重要,因为它会影响结果集.
| 归档时间: |
|
| 查看次数: |
8660 次 |
| 最近记录: |