如何将 master table 加入多个 details table 并在额外的 details 行中填充 NULL
How to join master table to multiple details table with extra rows of details cell filled with NULL
我不确定问题标题是否合适。我的问题类似于线程 How to Join Multiple Detail Tables to Header Table 。但是这个也给出了重复的记录。
这是我的情况
我有一个大师 table 和两个细节 table。
MasterID | Name
----------------------- // Master table
1 Item1
2 Item2
3 Item3
4 Item4
5 Item5
-----------------------
Det1ID | FKMasterID | Value
-----------------------------
1 1 Det1-Val1
2 1 Det1-Val2
3 2 Det1-Val3
Det2ID | FKMasterID | Value
-----------------------------
1 1 Det2-Val1
2 1 Det2-Val2
3 1 Det2-Val3
4 3 Det2-Val4
5 5 Det2-Val5
----------------------------------
表格有点像这样。
当我进行 required left-right joins 时,我以这种方式得到结果。
MasterID | Name | Det1ID | Det1Value | Det2ID | Det2Value
------------------------------------------------------------
1 Item1 1 Det1-Val1 1 Det2-Val1
1 Item1 1 Det1-Val1 2 Det2-Val2
1 Item1 1 Det1-Val1 3 Det2-Val3
1 Item1 2 Det1-Val2 1 Det2-Val1
1 Item1 2 Det1-Val2 2 Det2-Val2
1 Item1 2 Det1-Val2 3 Det2-Val3
2 Item2 3 Det1-Val3 NULL NULL
3 Item3 NULL NULL 4 Det2-Val4
4 Item4 NULL NULL NULL NULL
5 Item5 NULL NULL 5 Det2-Val5
-------------------------------------------------------------
我期望得到的是
MasterID | Name | Det1ID | Det1Value | Det2ID | Det2Value
------------------------------------------------------------
1 Item1 1 Det1-Val1 1 Det2-Val1
1 Item1 2 Det1-Val2 2 Det2-Val2
1 Item1 NULL NULL 3 Det2-Val3
2 Item2 3 Det1-Val3 NULL NULL
3 Item3 NULL NULL 4 Det2-Val4
4 Item4 NULL NULL NULL NULL
5 Item5 NULL NULL 5 Det2-Val5
------------------------------------------------------------
我不希望任何主条目的详细信息值重复。
有什么办法吗??只有用游标迭代才是办法??
一点帮助表示赞赏。
谢谢,
我不太确定,但我想你想要的是这个:
SELECT m.MasterID, m.Name, d1.DetailsID Det1ID, d1.Value Det1Value, d2.DetailsID Det2ID, d2.Value Det2Value
FROM Details1 d1
FULL OUTER JOIN Details2 d2 ON d1.FKMasterID = d2.FKMasterID AND d1.Value = d2.Value
RIGHT JOIN Master m ON d1.FKMasterID = m.MasterID OR d2.FKMasterID = m.MasterID
如果值匹配,这将只显示两个详细信息表,这似乎是您想要的?
事实证明它比我最初想象的要棘手一些,但下面应该可以解决问题。代码应该很容易解释。
WITH [master] AS(
SELECT * FROM (VALUES
(1, 'Item1')
,(2, 'Item2')
,(3, 'Item3')
,(4, 'Item4')
,(5, 'Item5')
) AS T(ID, Value)
),
Det1 AS (
SELECT * FROM (VALUES
(1, 1, 'Det1-Val1')
,(2, 1, 'Det1-Val2')
,(3, 2, 'Det1-Val3')
) AS T(ID, MasterID, Value)
),
Det2 AS (
SELECT * FROM (VALUES
(1, 1, 'Det2-Val1')
,(2, 1, 'Det2-Val2')
,(3, 1, 'Det2-Val3')
,(4, 3, 'Det2-Val4')
,(5, 5, 'Det2-Val5')
) AS T(ID, MasterID, Value)
),
Det1Numbered AS(
SELECT MasterID = M.ID ,
MasterValue = M.Value ,
Det1ID = D.ID ,
Det1Value = D.Value,
RowNr = ROW_NUMBER() OVER (PARTITION BY M.ID ORDER BY D.ID)
FROM [master] AS M
LEFT JOIN Det1 AS D
ON M.ID = D.MasterID
),
Det2Numbered AS(
SELECT MasterID = M.ID ,
MasterValue = M.Value ,
Det2ID = D.ID ,
Det2Value = D.Value,
RowNr = ROW_NUMBER() OVER (PARTITION BY M.ID ORDER BY D.ID)
FROM [master] AS M
LEFT JOIN Det2 AS D
ON M.ID = D.MasterID
)
SELECT MasterID = COALESCE(D1.MasterID, D2.MasterID),
MasterValue = COALESCE(D1.MasterValue, D2.MasterValue),
D1.Det1ID ,
D1.Det1Value ,
D2.Det2ID ,
D2.Det2Value
FROM Det1Numbered AS D1
FULL JOIN Det2Numbered AS D2
ON D1.MasterID = D2.MasterID
AND D2.RowNr = D1.RowNr
ORDER BY MasterID
编辑: 那里确实有一个小错误,我已经更新了上面的查询。解决方法是将 PARTITION BY D.MasterID
替换为 PARTITION BY M.ID
,现在每条主记录的 RowNr 从 1 开始,这在之前的版本中没有。
我不确定问题标题是否合适。我的问题类似于线程 How to Join Multiple Detail Tables to Header Table 。但是这个也给出了重复的记录。
这是我的情况
我有一个大师 table 和两个细节 table。
MasterID | Name
----------------------- // Master table
1 Item1
2 Item2
3 Item3
4 Item4
5 Item5
-----------------------
Det1ID | FKMasterID | Value
-----------------------------
1 1 Det1-Val1
2 1 Det1-Val2
3 2 Det1-Val3
Det2ID | FKMasterID | Value
-----------------------------
1 1 Det2-Val1
2 1 Det2-Val2
3 1 Det2-Val3
4 3 Det2-Val4
5 5 Det2-Val5
----------------------------------
表格有点像这样。
当我进行 required left-right joins 时,我以这种方式得到结果。
MasterID | Name | Det1ID | Det1Value | Det2ID | Det2Value
------------------------------------------------------------
1 Item1 1 Det1-Val1 1 Det2-Val1
1 Item1 1 Det1-Val1 2 Det2-Val2
1 Item1 1 Det1-Val1 3 Det2-Val3
1 Item1 2 Det1-Val2 1 Det2-Val1
1 Item1 2 Det1-Val2 2 Det2-Val2
1 Item1 2 Det1-Val2 3 Det2-Val3
2 Item2 3 Det1-Val3 NULL NULL
3 Item3 NULL NULL 4 Det2-Val4
4 Item4 NULL NULL NULL NULL
5 Item5 NULL NULL 5 Det2-Val5
-------------------------------------------------------------
我期望得到的是
MasterID | Name | Det1ID | Det1Value | Det2ID | Det2Value
------------------------------------------------------------
1 Item1 1 Det1-Val1 1 Det2-Val1
1 Item1 2 Det1-Val2 2 Det2-Val2
1 Item1 NULL NULL 3 Det2-Val3
2 Item2 3 Det1-Val3 NULL NULL
3 Item3 NULL NULL 4 Det2-Val4
4 Item4 NULL NULL NULL NULL
5 Item5 NULL NULL 5 Det2-Val5
------------------------------------------------------------
我不希望任何主条目的详细信息值重复。
有什么办法吗??只有用游标迭代才是办法?? 一点帮助表示赞赏。
谢谢,
我不太确定,但我想你想要的是这个:
SELECT m.MasterID, m.Name, d1.DetailsID Det1ID, d1.Value Det1Value, d2.DetailsID Det2ID, d2.Value Det2Value
FROM Details1 d1
FULL OUTER JOIN Details2 d2 ON d1.FKMasterID = d2.FKMasterID AND d1.Value = d2.Value
RIGHT JOIN Master m ON d1.FKMasterID = m.MasterID OR d2.FKMasterID = m.MasterID
如果值匹配,这将只显示两个详细信息表,这似乎是您想要的?
事实证明它比我最初想象的要棘手一些,但下面应该可以解决问题。代码应该很容易解释。
WITH [master] AS(
SELECT * FROM (VALUES
(1, 'Item1')
,(2, 'Item2')
,(3, 'Item3')
,(4, 'Item4')
,(5, 'Item5')
) AS T(ID, Value)
),
Det1 AS (
SELECT * FROM (VALUES
(1, 1, 'Det1-Val1')
,(2, 1, 'Det1-Val2')
,(3, 2, 'Det1-Val3')
) AS T(ID, MasterID, Value)
),
Det2 AS (
SELECT * FROM (VALUES
(1, 1, 'Det2-Val1')
,(2, 1, 'Det2-Val2')
,(3, 1, 'Det2-Val3')
,(4, 3, 'Det2-Val4')
,(5, 5, 'Det2-Val5')
) AS T(ID, MasterID, Value)
),
Det1Numbered AS(
SELECT MasterID = M.ID ,
MasterValue = M.Value ,
Det1ID = D.ID ,
Det1Value = D.Value,
RowNr = ROW_NUMBER() OVER (PARTITION BY M.ID ORDER BY D.ID)
FROM [master] AS M
LEFT JOIN Det1 AS D
ON M.ID = D.MasterID
),
Det2Numbered AS(
SELECT MasterID = M.ID ,
MasterValue = M.Value ,
Det2ID = D.ID ,
Det2Value = D.Value,
RowNr = ROW_NUMBER() OVER (PARTITION BY M.ID ORDER BY D.ID)
FROM [master] AS M
LEFT JOIN Det2 AS D
ON M.ID = D.MasterID
)
SELECT MasterID = COALESCE(D1.MasterID, D2.MasterID),
MasterValue = COALESCE(D1.MasterValue, D2.MasterValue),
D1.Det1ID ,
D1.Det1Value ,
D2.Det2ID ,
D2.Det2Value
FROM Det1Numbered AS D1
FULL JOIN Det2Numbered AS D2
ON D1.MasterID = D2.MasterID
AND D2.RowNr = D1.RowNr
ORDER BY MasterID
编辑: 那里确实有一个小错误,我已经更新了上面的查询。解决方法是将 PARTITION BY D.MasterID
替换为 PARTITION BY M.ID
,现在每条主记录的 RowNr 从 1 开始,这在之前的版本中没有。