4

次のテーブルがあります。

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

このためのフィドルを作成し、2 つの個別のクエリの結合を使用してソリューションを提供しました。user_groupsgroup_Aおよびの単一の結合でグループ名を選択するテーブルを決定できるユニオンなしで実行できますgroup_Bか?

4

2 に答える 2

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

SQL フィドルの例

于 2012-10-23T14:30:02.700 に答える
6

左結合を使用して結合なしでこれを行うことができます (暗黙の結合は 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;

私のクエリを追加したあなたのフィドル

于 2012-10-23T14:39:19.390 に答える