在SQL中使用WHERE

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)

Kin*_*chy 7

简而言之,第一个查询在连接对连接表应用过滤器,而第二个查询连接到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子句中会导致相同的操作.