SQL:跨两个层次结构的完全外部联接

Posted

技术标签:

【中文标题】SQL:跨两个层次结构的完全外部联接【英文标题】:SQL: Full Outer Join across two hierarchies 【发布时间】:2015-12-28 23:28:24 【问题描述】:

假设我有一张装运零件表和收据上零件表。我想将我发货的商品与我收到的商品进行匹配,并通过一个共同的发货编号绑定在一起。

装运表

SHIPMENT NO    PART NO
 1              A
 1              B
 2              A
 2              C

收据表

SHIPMENT NO    PART NO
 1              A
 1              C
 2              B
 3              A

期望的结果

SHIP. SHIP. NO    SHIP. PART NO    RPT. SHIP. NO    RPT. PART NO
 1                 A                1                A
 1                 B                1                NULL
 1                 NULL             1                C
 2                 A                2                NULL
 2                 NULL             2                C
 NULL              NULL             3                A

因此,想法是有一个完整的外部连接,显示所有不同的发货编号和发货和收据的相应零件编号,但在匹配的地方将它们连接在一起。即使零件编号不匹配,问题仍然会出现在 Shipment No 上。

基本上有两种连接条件,其中一种是完全可选的。

我确定解决方案非常简单,但如果不使用联合,我看不到如何做到这一点。

【问题讨论】:

总是尝试包含一个 rdbms 标签,SqlServer,mysql 那么,为了确认,“零件号”连接条件是可选的吗? 【参考方案1】:

试试这个

CREATE TABLE Shipment ([SHIPMENT NO] int, [PART NO] varchar(1))    
INSERT INTO Shipment ([SHIPMENT NO], [PART NO])
VALUES
    (1, 'A'),
    (1, 'B'),
    (2, 'A'),
    (2, 'C')
;
CREATE TABLE Receipt ([SHIPMENT NO] int, [PART NO] varchar(1));    
INSERT INTO Receipt  ([SHIPMENT NO], [PART NO])
VALUES
    (1, 'A'),
    (1, 'C'),
    (2, 'B'),
    (3, 'A')
;

SELECT 
     X.ShipmentShipNO AS 'SHIP. SHIP. NO'   
    ,s.[PART NO] AS 'SHIP. PART NO'
    ,X.ReceiptShipNO AS 'RPT. SHIP. NO'
    ,r.[PART NO] AS 'RPT. PART NO'

FROM Shipment s
FULL OUTER JOIN Receipt r ON s.[SHIPMENT NO] = r.[SHIPMENT NO] AND s.[PART NO] = r.[PART NO]
FULL OUTER JOIN 
                (
                    SELECT DISTINCT
                        s.[SHIPMENT NO] AS'ShipmentShipNO'
                        ,r.[SHIPMENT NO] AS'ReceiptShipNO'
                        FROM Shipment s
                        FULL JOIN Receipt r ON s.[SHIPMENT NO] = r.[SHIPMENT NO]
                )X ON r.[SHIPMENT NO] = X.ReceiptShipNO OR s.[SHIPMENT NO] = X.ShipmentShipNO
ORDER BY 3


DROP TABLE Shipment
DROP TABLE Receipt

【讨论】:

欢迎来到***。我认为你做对了。你有没有检查sqlFiddle当你想显示一个有效的答案时会有帮助。有一个很好的text to ddl 函数来帮助准备数据模式。还有一个纯文本输出,因此您可以将输出粘贴为答案而不是图片 太棒了!我知道有一种基本的连接样式可以实现这一点,但以前没有理由使用full join。 ...这很尴尬,因为我什至在我的帖子中使用了短语full outer join... @Justin,它们(完全连接,完全外部连接)都是相同的。所以就像左连接/左外连接和右/右外连接一样【参考方案2】:

使用FULL JOIN

SQL Fiddle Demo

SELECT S.*, R.*
FROM Shipment S 
FULL JOIN Receipt R
 ON S.[SHIPMENT NO] = R.[SHIPMENT NO]
AND S.[PART NO] = R.[PART NO]

【讨论】:

以上是关于SQL:跨两个层次结构的完全外部联接的主要内容,如果未能解决你的问题,请参考以下文章

MS Access 完全外部联接中的莫名行为?

两个表的完全联接,两个表都有条件

SQL联接 外联接 内联接 完全联接 交叉联接

SQL Server-外部联接基础回顾(十三)

需要帮助在 MS Access 中实施完全外部联接

详解T-SQL的联接机制