如何将 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 开始,这在之前的版本中没有。