Соединить таблицу с одной таблицей, если условие 1 истинно, и с другой таблицей, если условие 1 ложно?

У меня есть следующие таблицы:

User_Group

id  group_id  group_type
------------------------
1   100       A
1   100       B
2   101       B
2   102       A

Group_A

id   name
---------
100  A
101  B
102  C

Group_B

id   name
---------
100  D
101  E
102  F

Я хочу, чтобы имена групп всех пользователей (используя array.agg()). Мы должны получить имя группы из группы A, если тип группы пользователя = A, и из группы B, если тип группы пользователя = B. Результат должен быть:

userid  groups
--------------
1       A,D
2       E,C

Я создал скрипку для этого и дал решение, используя объединение двух отдельных запросов. Можно ли это сделать без объединения, в котором я могу решить, из какой таблицы выбрать имя группы, с помощью одного объединения user_groups, group_A а также group_B?

2 ответа

Решение
select ug.id, array_agg(
    case ug.group_type 
        when 'A' then g_a.name 
        when 'B' then g_b.name 
        else 'N/A' 
    end)
from user_groups ug
left outer join group_A g_a on ug.group_id = g_a.id
left outer join group_B g_b on ug.group_id = g_b.id
group by ug.id

Пример SQL Fiddle

Вы можете сделать это без объединения, используя левые объединения (я бы посоветовал использовать явные объединения в любом случае, поскольку неявные объединения устарели на 20 лет. Аарон Бертран написал хороший блог о том, почему). Group_Type может стать условием объединения, то есть таблица объединяется только тогда, когда найден правильный тип группы:

SELECT  ug.ID, ARRAY_AGG(COALESCE(a.Name, b.Name))
FROM    User_Groups ug
        LEFT JOIN group_A a
            ON a.ID = ug.group_ID
            AND ug.Group_Type = 'A'
        LEFT JOIN group_B b
            ON b.ID = ug.group_ID
            AND ug.Group_Type = 'B'
WHERE   COALESCE(a.ID, b.ID) IS NOT NULL -- ENSURE AT LEAST ONE GROUP IS MATCHED
GROUP BY ug.ID;

Однако я был бы склонен использовать UNION Still, но переместил его следующим образом:

SELECT  ug.ID, ARRAY_AGG(Name)
FROM    User_Groups ug
        INNER JOIN
        (   SELECT  'A' AS GroupType, ID, Name
            FROM    Group_A
            UNION ALL
            SELECT  'B' AS GroupType, ID, Name
            FROM    Group_B
        ) G
            ON g.GroupType = ug.Group_Type
            AND g.ID = ug.Group_ID
GROUP BY ug.ID;

Твоя скрипка с моими запросами добавлена

Другие вопросы по тегам