关于与内连接结合使用时的外连接
Posted
技术标签:
【中文标题】关于与内连接结合使用时的外连接【英文标题】:Regarding Outer Joins When Used In Conjunction With Inner Joins 【发布时间】:2018-08-15 21:52:02 【问题描述】:问题:我是一名初级 SQL 用户,想验证我对 LEFT OUTER JOINS 的理解(使用 Adventure Works 数据库)。我已经了解了一个简单的 LEFT OUTER JOIN 是如何工作的。它在 LEFT 侧获取整个表并匹配它可以找到的任何正确值,否则它为 RIGHT 侧留下 NULL。我有点困惑的地方是当你有一系列的内部连接,然后是一个左外部连接。所以我的问题是针对下面的代码,考虑到左侧,哪一侧是 LEFT OUTER JOIN?是FROM后的值吗:
FROM **Person.Person** AS Pp
或者是否引用了 INNER JOIN 表之一?请参阅下面的代码,谢谢!
DECLARE @Date AS NVARCHAR(60)
SET @Date = '2013-01-01'
DECLARE @Date1 AS NVARCHAR(60)
SET @Date1 = '2013-12-31'
DECLARE @Date2 AS NVARCHAR(60)
SET @Date2 = '2012-01-01'
DECLARE @Date3 AS NVARCHAR(60)
SET @Date3 = '2012-12-31'
SELECT Pp.FirstName + ' ' + Pp.LastName AS 'Name',
Ph.PhoneNumber,Em.EmailAddress, St.Name AS 'Sales Territory',
(
SELECT SUM(Soh.TotalDue) AS 'TEST'
FROM Sales.SalesOrderHeader AS Soh
WHERE Soh.SalesPersonID = Pp.BusinessEntityID
) AS 'Total Revenue',
(
((SELECT SUM(Soh.TotalDue) FROM Sales.SalesOrderHeader AS Soh WHERE
Soh.OrderDate BETWEEN @Date AND @Date1 AND Soh.SalesPersonID =
Pp.BusinessEntityID)-
(SELECT SUM(Soh.TotalDue) FROM Sales.SalesOrderHeader AS Soh WHERE
Soh.OrderDate BETWEEN @Date2 AND @Date3 AND Soh.SalesPersonID =
Pp.BusinessEntityID))/
(SELECT SUM(Soh.TotalDue) FROM Sales.SalesOrderHeader AS Soh WHERE
Soh.OrderDate BETWEEN @Date2 AND @Date3 AND Soh.SalesPersonID =
Pp.BusinessEntityID)
) * 100 AS 'Percent Change In Rev'
FROM Person.Person AS Pp
INNER JOIN Person.PersonPhone AS Ph
ON Pp.BusinessEntityID = Ph.BusinessEntityID
INNER JOIN Person.EmailAddress AS Em
ON Pp.BusinessEntityID = Em.BusinessEntityID
INNER JOIN Sales.SalesPerson AS Sp
ON Sp.BusinessEntityID = Pp.BusinessEntityID
LEFT OUTER JOIN Sales.SalesTerritory AS St
ON Sp.TerritoryID = St.TerritoryID
ORDER BY 'Total Revenue' DESC
【问题讨论】:
【参考方案1】:没有左外连接这样的东西。只有 LEFT、RIGHT、INNER 和 FULL (OUTER) 连接。
LEFT 从左侧(FROM 侧)获取所有值,并将它们与右侧的任何结果进行匹配。
右连接只是执行相反的表,即作为完整结果集连接的表。
Inner 只查找匹配项。
Outer 找到一切,并连接它可以连接的那些。
【讨论】:
LEFT OUTER JOIN
是有效的 ANSI/ISO 语法,并且在我能想到的所有数据库中都受支持。 OUTER
是可选的,因此通常表示为LEFT JOIN
。
我同意 Gordon 的观点,LEFT OUTER JOIN 和 LEFT JOIN 是一回事。
我对外连接短语的问题是它混淆了实际的外连接函数。它混淆了作为标准的 LEFT JOIN 语法。【参考方案2】:
当您有一系列连接时,例如:
a inner join b inner join c inner join d left join e
那么这被视为:
(((a inner join b) inner join c) inner join d) left join e
这种语义解释,而不是必须如何执行连接。这种解释与连接的类型无关。这就是在不带括号的 FROM
子句中解释连接的方式。
现在,括号对理解没有太大帮助。所以,发生的事情是初始表都是内部连接在一起的。这是结果集的行集。然后将left join
应用于这组行。它实际上是:
(a inner join b inner join c inner join d) left join e
对于几乎所有目的,我发现内连接后左连接可以满足我的外连接需求。例如,我从不使用right join
。以另一种顺序混合内连接和外连接——嗯,这会让我很头疼,试图弄清楚结果集中是什么,什么不是。
【讨论】:
以上是关于关于与内连接结合使用时的外连接的主要内容,如果未能解决你的问题,请参考以下文章