次の構造の行のテーブルがあり、各行にname TEXT, favorite_colors TEXT[], group_name INTEGER
は全員のお気に入りの色とその人が属するグループのリストがあります。GROUP BY group_name
各グループで最も一般的な色のリストを返すにはどうすればよいですか?
int[] && int[]
オーバーラップを設定しint[] & int[]
、交差点を取得してから、カウントしてランク付けする他の何かを組み合わせて実行できますか?
次の構造の行のテーブルがあり、各行にname TEXT, favorite_colors TEXT[], group_name INTEGER
は全員のお気に入りの色とその人が属するグループのリストがあります。GROUP BY group_name
各グループで最も一般的な色のリストを返すにはどうすればよいですか?
int[] && int[]
オーバーラップを設定しint[] & int[]
、交差点を取得してから、カウントしてランク付けする他の何かを組み合わせて実行できますか?
クイック&ダーティ:
SELECT group_name, color, count(*) AS ct
FROM (
SELECT group_name, unnest(favorite_colors) AS color
FROM tbl
) sub
GROUP BY 1,2
ORDER BY 1,3 DESC;
LATERAL JOIN
Postgres 9.3 以降では、これはよりクリーンな形式です。
SELECT group_name, color, count(*) AS ct
FROM tbl t, unnest(t.favorite_colors) AS color
GROUP BY 1,2
ORDER BY 1,3 DESC;
上記はの省略形です
...
FROM tbl t
JOIN LATERAL unnest(t.favorite_colors) AS color ON TRUE
...
また、他の と同様に、最初のクエリと同様に、INNER JOIN
色 ( ) のない行を除外します。favorite_colors IS NULL
そのような行を結果に含めるには、代わりに次を使用します。
SELECT group_name, color, count(*) AS ct
FROM tbl t
LEFT JOIN LATERAL unnest(t.favorite_colors) AS color ON TRUE
GROUP BY 1,2
ORDER BY 1,3 DESC;
次のステップでグループごとに「最も一般的な」色を簡単に集計できますが、最初に「最も一般的な色」を定義する必要があります...
コメントに従って、3回以上出現する色を選択してください。
SELECT t.group_name, color, count(*) AS ct
FROM tbl t, unnest(t.favorite_colors) AS color
GROUP BY 1,2
HAVING count(*) > 3
ORDER BY 1,3 DESC;
配列の上位の色を (降順で) 集計するには:
SELECT group_name, array_agg(color) AS top_colors
FROM (
SELECT group_name, color
FROM tbl t, unnest(t.favorite_colors) AS color
GROUP BY 1,2
HAVING count(*) > 3
ORDER BY 1, count(*) DESC
) sub
GROUP BY 1;