Извлечь родительскую запись из дочерних записей в SQL - PullRequest
0 голосов
/ 24 мая 2018

У меня есть следующие данные, которые выглядят как приведенная ниже таблица

+----------+-----------+-------------+
| Child_ID | Parent_ID | Identifier  |
+----------+-----------+-------------+
| C1       | p1        | IN          |
| C2       | p1        | OUT         |
| C1       | p2        | IN          |
| C2       | p2        | OUT         |
| C1       | p3        | IN          |
| C2       | p3        | OUT         |
+----------+-----------+-------------+

Мне нужно вывести данные таким образом, чтобы я мог отобразить родительскую запись в отдельной строке, связывающей 2 дочерних идентификатора на основеидентификатор.

Желаемый результат:

+----+-----------+---------+----------+------------+
| ID | Parent_ID | Child_1 | Child_2  | Identifier |
+----+-----------+---------+----------+------------+
| C1 | P1        | NULL    | NULL     | IN         |
| C2 | P1        | NULL    | NULL     | OUT        |
| P1 | NULL      | C1      | C2       | IN         |
| C1 | P2        | NULL    | NULL     | IN         |
| C2 | P2        | NULL    | NULL     | OUT        |
| P2 | NULL      | C1      | C2       | IN         |
+----+-----------+---------+----------+------------+

Для достижения этой цели я запустил следующий запрос, в котором я попытался оставить присоединение к отдельной родительской записи, а затем UNION, чтобы найти дочерние записи.

-- Parent 
Select c1.PARENT_ID as ID,
       Parent_Id,
       c1.Child_ID as Child_1
       c2.Child_ID as Child_2
       c1.Identifier
from sampletable as c1
left join sampletable as c2
on c2.PARENT_ID = c1.PARENT_ID 
and c2.Identifier = 'OUT'
where c1.Identifier = 'IN'

UNION

-- CHILD
Select child_id as ID,
       Parent_id,
       CASE when Identifier = 'IN' then Child_ID
       Else NULL END As Child_1,
       CASE when Identifier = 'OUT' then Child_ID
       Else NULL END As Child_2,
       Identifier
from sampletable 
where parent_id is not null

Пожалуйста, кто-нибудь может указать, что я здесь делаю неправильно.

1 Ответ

0 голосов
/ 24 мая 2018

Выберите детей такими, какие они есть.

Для родителей используйте подзапрос в FROM, чтобы получить набор различных Parent_ID s.При условии, что есть только два дочерних элемента, вы можете использовать другие подзапросы, выбрав min(Child_ID) или max(Child_ID) соответственно в списке столбцов.

UNION ALL оба результата.

Поместить внешний запроспо результату UNION ALL и закажите его по coalesce(Parent_ID, ID), CASE WHEN ID IS NULL THEN 1 ELSE 0 END, ID, чтобы достичь того порядка, который вы хотите.CASE - это хак для обеспечения того, чтобы ID был NULL последним.(Я не уверен, что NULLS стоит первым или последним в SQL Server и слишком ленив, чтобы искать его прямо сейчас. Или, если я правильно помню, есть опция для всей базы данных?самая безопасная ставка.)

SELECT * 
       FROM (SELECT Child_ID ID,
                    Parent_ID,
                    NULL Child_1,
                    NULL Child_2,
                    Identifier
                    FROM sampletable
                    UNION ALL
                    SELECT x.Parent_ID ID,
                           NULL Parent_ID,
                           (SELECT min(Child_ID)
                                  FROM sampletable y
                                  WHERE y.Parent_ID = y.Parent_ID) Child_1,
                           (SELECT max(Child_ID)
                                   FROM sampletable y
                                   WHERE y.Parent_ID = y.Parent_ID) Child_2,
                           'IN' Identifier
                           FROM (SELECT DISTINCT Parent_ID
                                        FROM sampletable) x) u
       ORDER BY coalesce(Parent_ID,
                         ID),
                CASE
                  WHEN ID IS NULL
                    THEN 1
                  ELSE
                    0
                END,
                ID;

SQL Fiddle

...