我有以下表格:
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
我为此创建了一个fiddle,并使用两个独立查询的并集给出了解决方案。是否可以在没有联合的情况下完成,我可以通过user_groups
,group_A
和group_B
的单一联接决定从哪个表中选择组名?
答案 0 :(得分:8)
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
答案 1 :(得分:6)
你可以在没有使用左连接的联合的情况下做到这一点(我建议使用显式连接,因为隐式连接已经过时了20年Aaron Bertrand has written a good blog as to why)。 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;