【问题标题】:Group select statements together by common column in sql-server通过 sql-server 中的公共列将 select 语句组合在一起
【发布时间】:2019-11-06 07:34:33
【问题描述】:

我需要根据一个公共列将两个表组合在一起。通常我只会在特定列上使用内部连接(我们称之为 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 关系(表 a 中的一个条目可以从表 B 和 C 中的多个条目中引用)。表 B 和表 C 不相互引用,完全相互独立。

【问题讨论】:

  • 您能否为您的表ABC 提供示例数据? ABAC 之间的关系是一对一的,还是一对多的关系?如果C 有相关行,而B 只有 2 行,你会看到什么?
  • @Larnu 我编辑了我的问题
  • 我没有看到任何示例数据?
  • ID_C 在哪里?

标签: sql sql-server database join union


【解决方案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

【讨论】:

  • 很遗憾没有,因为表 B 和 C 都有许多其他列(我编辑了我的问题)
【解决方案2】:

你应该使用联合运算符

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

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

【讨论】:

    【解决方案3】:

    看起来你真正想要的是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 值。

    【讨论】:

      【解决方案4】:

      有点摸不着头脑,但它会根据样本数据为您提供所需的结果集:

      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

      【讨论】:

      • 结果看起来不像 OP 提供的,我不认为它是示例数据。看起来像 UNION / UNION ALL 仅此而已,Q 仍然不清楚,值得一份简历。
      • ORDER BY 应该是 V.T, @Sami。固定。
      【解决方案5】:

      我猜这是 JOIN 的 UNION

      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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-11
        • 1970-01-01
        • 2017-12-13
        • 1970-01-01
        • 2016-03-18
        • 2018-02-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多