SQL:跨两个层次结构的完全外部联接
SQL: Full Outer Join across two hierarchies
假设我有一个 table 的零件在货件上,零件在收据上。我想将我发货的东西与我收到的东西进行比较,并通过一个共同的发货编号绑定在一起。
发货Table
SHIPMENT NO PART NO
1 A
1 B
2 A
2 C
收货Table
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
所以我们的想法是,有一个完整的外部连接,显示所有不同的装运号和装运和收据的各自零件号,但在它们匹配的地方将它们连接在一起。即使零件号不匹配,复杂功能仍会加入发货编号。
基本上有两个连接条件,其中一个是完全可选的。
我确定解决方案非常简单,但我不知道如何不使用联合来做到这一点。
使用FULL JOIN
SELECT S.*, R.*
FROM Shipment S
FULL JOIN Receipt R
ON S.[SHIPMENT NO] = R.[SHIPMENT NO]
AND S.[PART NO] = R.[PART NO]
试试这个
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
假设我有一个 table 的零件在货件上,零件在收据上。我想将我发货的东西与我收到的东西进行比较,并通过一个共同的发货编号绑定在一起。
发货Table
SHIPMENT NO PART NO
1 A
1 B
2 A
2 C
收货Table
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
所以我们的想法是,有一个完整的外部连接,显示所有不同的装运号和装运和收据的各自零件号,但在它们匹配的地方将它们连接在一起。即使零件号不匹配,复杂功能仍会加入发货编号。
基本上有两个连接条件,其中一个是完全可选的。
我确定解决方案非常简单,但我不知道如何不使用联合来做到这一点。
使用FULL JOIN
SELECT S.*, R.*
FROM Shipment S
FULL JOIN Receipt R
ON S.[SHIPMENT NO] = R.[SHIPMENT NO]
AND S.[PART NO] = R.[PART NO]
试试这个
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