使用group by查找数组中最常见的元素

时间:2014-01-09 23:24:04

标签: sql postgresql aggregate-functions postgresql-9.3 lateral

我有一个行表,其中包含以下结构name TEXT, favorite_colors TEXT[], group_name INTEGER,其中每行都有一个列表,列出了每个人最喜欢的颜色以及该人所属的组。我怎样才能GROUP BY group_name并返回每组中最常见颜色的列表?

你可以组合使用int[] && int[]设置重叠,int[] & int[]来获取交集,然后还有其他东西可以统计和排名吗?

1 个答案:

答案 0 :(得分:4)

又快又脏:

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;

-> SQLfiddle展示所有。