将选择语句按sql-server中的公共列分组在一起

时间:2019-06-24 13:20:27

标签: sql sql-server database join union

我需要根据同一列将两个表组合在一起。通常,我只会在特定列上使用内部联接(我们称其为parentID),但我需要将结果放在单独的行中。

表A:

ID, ...

表B:

ID, ParentID, SomeColB, ...

表C:

ID, ParentID, SomeColC, ...

ParentID指向表A的ID。结果应如下所示:

ParentID  ID_A  ID_B  SomeColB  SomeColC
1         10    20    'VAL_B1'  NULL
1         10    20    NULL      'VAL_C1'
2         11    21    'VAL_B2'  NULL
2         11    21    NULL      'VAL_C2'
...

因此,我想在从表B和C中选择值之间进行选择,并将其余的列保留为空。我该怎么办?

我尝试将它们连接在一起,但这导致结果被放在一行中。

编辑:表B和C与表A具有1-n关系(可以从表B和C中的多个条目引用表a中的一个条目)。表B和C彼此不引用,彼此完全独立。

5 个答案:

答案 0 :(得分:1)

类似的东西对您有用吗?我已经使用UNION来获取每个ParentID的两组数据:

   SELECT
        *
    FROM (
        SELECT
            ParentID,
            ID_A,
            ID_B,
            SomeCol B,
            NULL AS SomeColC
        FROM
            TableA
        UNION
        SELECT
            ParentID,
            ID_A,
            ID_B,
            NULL AS SomeColB,
            SomeColC
        FROM
            TableB
        )
    ORDER BY
        ParentID,
        SomeColB,
        SomeColC

答案 1 :(得分:0)

您应该使用联合运算符

SELECT  IDA, ParentIDA, SomeColA FROM first_table  
UNION  
SELECT  IDB, ParentIDB, SomeColB FROM second_table  

UNION将跳过重复的内容 如果要显示重复记录,则应使用UNION ALL运算符

答案 2 :(得分:0)

看起来您真正想要的是LEFT OUTER JOIN

带有相关字段的精简版本看起来像这样...

select a.ID as ParentID, b.SomeCol as SomeColB, c.SomeCol as SomeColC
from tableA a
left outer join tableB b
on b.ID = a.ID
left outer join tableC c
on c.ID = a.ID
;

左外部联接包括联接左侧表中的不匹配行,为联接中右侧表中未匹配记录的字段提供NULL值。

答案 3 :(得分:0)

在黑暗中有点刺破,但它会根据示例数据为您提供所需的结果集:

WITH A AS(
    SELECT ID
    FROM (VALUES(1),(2)) V(ID)),
B AS(
    SELECT V.ID,
           V.ParentID,
           V.ColB
    FROM (VALUES(1, 10,'Val_B1'),
                (2,11,'Val_B2'))V(ParentID,ID, ColB)),
C AS(
    SELECT V.ID,
           V.ParentID,
           V.ColC
    FROM (VALUES(1,20,'Val_C1'),
                (2,21,'Val_C2'))V(ParentID,ID, ColC))
SELECT A.ID AS ParentID,
       B.ID AS ID_A,
       C.ID AS ID_B,
       B.ColB,       
       C.ColC
FROM A
     CROSS APPLY (VALUES('B'),('C'))V(T)
     LEFT JOIN B ON A.ID = B.ParentID
                AND V.T = 'B'
     LEFT JOIN C ON A.ID = C.ParentID
                AND V.T = 'C'
ORDER BY A.ID,
         V.T;

DB<>fiddle

答案 4 :(得分:0)

我猜这是一个联合的联盟

SELECT A.ID AS ParentID, B.ID AS ID_B, null as ID_C, B.SomeColB, null as SomeColC --, ..      
FROM A
JOIN B ON A.ID = B.ParentID
UNION
SELECT A.ID AS ParentID, null, c.ID as ID_C, null, C.SomeColC --, .. 
FROM A
JOIN C ON A.ID = C.ParentID
ORDER BY ParentID, ID_B, ID_C;

要重复ID,请再进行一次SELECT包裹:

SELECT ParentID
 , max(ID_B) OVER(PARTITION BY ParentID) AS ID_B
 , max(ID_C) OVER(PARTITION BY ParentID) AS ID_C 
 , SomeColB, SomeColC --, --
FROM (
    SELECT A.ID AS ParentID, B.ID AS ID_B, null as ID_C, B.SomeColB, null as SomeColC --, ..      
    FROM A
    JOIN B ON A.ID = B.ParentID
    UNION
    SELECT A.ID AS ParentID, null, c.ID as ID_C, null, C.SomeColC --, .. 
    FROM A
    JOIN C ON A.ID = C.ParentID) t
ORDER BY ParentID, ID_B, ID_C;