我不明白下面给出的两种编码之间的区别。第一个用于WHERELEFT JOIN。第二个代码使用AND。我不明白从每种编码中得到的输出是什么?
WHERE
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;
简而言之,第一个查询在对联接的表 进行 联接 之后 将过滤器应用于它们,而第二个查询在将其联接到Customer 之前 将其应用于SalesOrderHeader 。区别很重要。
假设您的Customer表具有某些SalesIDHeader表中不存在的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 | + ---------------- + ----------- +
当您执行左外部联接时
SELECT c.FirstName, c.LastName, oh.SalesOrderNumber FROM SalesLT.Customer AS c LEFT OUTER JOIN SalesLT.SalesOrderHeader AS oh ON c.CustomerID = oh.CustomerID
您将看到Customer表中的所有记录(因为它是 左侧 表),但是SalesOrderHeader表中所有不匹配的记录都将显示为空。因此,在我们的示例中,您将获得
Resulting Joined Table + --------- + -------- + ---------------- + | Firstname | Lastname | SalesOrderNumber | + --------- + -------- + ---------------- + | Bob | Dylan | 1681351 | | Donald | Trump | null | | Guy | Gisbon | 1354894 | | Guy | Gisbon | 1351666 | | Megan | Meganson | null | + --------- + -------- + ---------------- +
现在,如果您应用where子句
WHERE oh.SalesOrderNumber IS NULL
您正在选择结果表的子集,其中SalesOrderNumber为null。在这里,你会得到
Filter in where clause + --------- + -------- + ---------------- + | Firstname | Lastname | SalesOrderNumber | + --------- + -------- + ---------------- + | Donald | Trump | null | | Megan | Meganson | null | + --------- + -------- + ---------------- +
现在让我们看一下第二个查询,联接条件中包含空过滤器。SQL将从SalesOrderHeader表中查找空的SalesOrderNumbers。在我们的示例中,我们没有任何空记录,因此您实际上是将Customer Table连接到一个空的SalesOrderHeader表。结果看起来像
Filter in join condition + --------- + -------- + ---------------- + | Firstname | Lastname | SalesOrderNumber | + --------- + -------- + ---------------- + | Bob | Dylan | null | | Donald | Trump | null | | Guy | Gisbon | null | | Megan | Meganson | null | + --------- + -------- + ---------------- +
此区别仅对外部联接很重要。如果您使用内部联接,则将过滤器置于联接条件或where子句中会得到相同的结果。