Myu*_*ran -2 sql t-sql left-join
我不明白下面给出的两种编码之间的区别.第一个用于WHERELEFT JOIN.第二个代码使用AND.我不明白从每个编码中得到的输出是什么?
SELECT c.FirstName, c.LastName, oh.SalesOrderNumber
FROM SalesLT.Customer AS c
LEFT OUTER JOIN SalesLT.SalesOrderHeader AS oh
ON c.CustomerID = oh.CustomerID
WHERE oh.SalesOrderNumber IS NULL
ORDER BY c.CustomerID;
SELECT c.FirstName, c.LastName, oh.SalesOrderNumber
FROM SalesLT.Customer AS c
LEFT OUTER JOIN SalesLT.SalesOrderHeader AS oh
ON c.CustomerID = oh.CustomerID
AND oh.SalesOrderNumber IS NULL
ORDER BY c.CustomerID;
Run Code Online (Sandbox Code Playgroud)
简而言之,第一个查询在连接后对连接表应用过滤器,而第二个查询在连接到Customer 之前将其应用于SalesOrderHeader .区别很重要.
假设您的Customer表具有SalesOrderHeader表中不存在的某些CustomerID.例如,请考虑以下两个表
Customer Table:
+ --------- + -------- + ---------- +
| Firstname | Lastname | CustomerID |
+ --------- + -------- + ---------- +
| Bob | Dylan | 1 |
| Donald | Trump | 2 |
| Me Myself | and I | 14 |
| Guy | Gisbon | 86 |
| Megan | Meganson | 87 |
+ --------- + -------- + ---------- +
SalesOrderHeader Table:
+ ---------------- + ----------- +
| SalesOrderNumber | CustomerID |
+ ---------------- + ----------- +
| 1681351 | 1 |
| 1354894 | 86 |
| 1354900 | 13 |
| 1351666 | 86 |
+ ---------------- + ----------- +
Run Code Online (Sandbox Code Playgroud)
执行左外连接时
SELECT c.FirstName, c.LastName, oh.SalesOrderNumber
FROM SalesLT.Customer AS c
LEFT OUTER JOIN SalesLT.SalesOrderHeader AS oh
ON c.CustomerID = oh.CustomerID
Run Code Online (Sandbox Code Playgroud)
您将看到Customer表中的所有记录(因为它是左表),但SalesOrderHeader表中的任何不匹配记录都将显示为空.所以在我们的例子中,你会得到
Resulting Joined Table
+ --------- + -------- + ---------------- +
| Firstname | Lastname | SalesOrderNumber |
+ --------- + -------- + ---------------- +
| Bob | Dylan | 1681351 |
| Donald | Trump | null |
| Guy | Gisbon | 1354894 |
| Guy | Gisbon | 1351666 |
| Megan | Meganson | null |
+ --------- + -------- + ---------------- +
Run Code Online (Sandbox Code Playgroud)
现在,如果你应用where子句
WHERE oh.SalesOrderNumber IS NULL
Run Code Online (Sandbox Code Playgroud)
您正在选择SalesOrderNumber为null的结果表的子集.在这里,你会得到
Filter in where clause
+ --------- + -------- + ---------------- +
| Firstname | Lastname | SalesOrderNumber |
+ --------- + -------- + ---------------- +
| Donald | Trump | null |
| Megan | Meganson | null |
+ --------- + -------- + ---------------- +
Run Code Online (Sandbox Code Playgroud)
现在让我们看一下第二个查询,其中null过滤器包含在连接条件中.SQL将从SalesOrderHeader表中查找null SalesOrderNumbers.在我们的示例中,我们没有任何空记录,因此您实际上是将Customer表连接到空的SalesOrderHeader表.结果看起来像
Filter in join condition
+ --------- + -------- + ---------------- +
| Firstname | Lastname | SalesOrderNumber |
+ --------- + -------- + ---------------- +
| Bob | Dylan | null |
| Donald | Trump | null |
| Guy | Gisbon | null |
| Megan | Meganson | null |
+ --------- + -------- + ---------------- +
Run Code Online (Sandbox Code Playgroud)
这种区别仅对外连接很重要.如果您正在使用内部联接,则将过滤器置于连接条件或where子句中会导致相同的操作.