Группировать операторы выбора вместе по общему столбцу в sql-сервере - PullRequest
0 голосов
/ 24 июня 2019

Мне нужно объединить две таблицы вместе на основе общего столбца.Обычно я бы просто использовал внутреннее соединение в конкретном столбце (давайте назовем его parentID), но мне нужно, чтобы результаты были в отдельных строках.

Таблица A:

ID, ...

Таблица B:

ID, ParentID, SomeColB, ...

Таблица C:

ID, ParentID, SomeColC, ...

ParentID указывает на идентификатор таблицы AРезультат должен выглядеть следующим образом:

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 имеют отношение 1-n к таблицеA (на одну запись в таблице a можно ссылаться из нескольких записей в таблицах B и C).Таблицы B и C не ссылаются друг на друга и полностью независимы друг от друга.

Ответы [ 5 ]

1 голос
/ 24 июня 2019

Хотелось бы что-нибудь подобное для вас? Я использовал 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
0 голосов
/ 24 июня 2019

Полагаю, это СОЮЗ СОЕДИНЕНИЙ

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;

Для повторения идентификаторов оберните его еще одним 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;
0 голосов
/ 24 июня 2019

Бит в темноте, но он дает вам нужный набор результатов на основе данных примера:

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 <> скрипка

0 голосов
/ 24 июня 2019

Похоже, что вы действительно хотите, это 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 значения для полей, поступающих из несопоставленных записей в таблице справа в объединении.

0 голосов
/ 24 июня 2019

Вы должны использовать оператор объединения

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

UNION пропустит записанные дубликаты, если вы хотите показать дубликаты записей, вам следует использовать оператор UNION ALL

...