关于与内连接结合使用时的外连接

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。以另一种顺序混合内连接和外连接——嗯,这会让我很头疼,试图弄清楚结果集中是什么,什么不是。

【讨论】:

以上是关于关于与内连接结合使用时的外连接的主要内容,如果未能解决你的问题,请参考以下文章

左连接,右连接与内连接

SQL中外连接与内连接之间的区别

多表查询与内连接,外连接

左连接与右连接,外连接与内连接

SQL 中 3 个条件的联合与内连接

外网客户端访问校园内网的服务器——socket连接