Create array in SELECT

前端 未结 3 2080
别跟我提以往
别跟我提以往 2021-02-09 07:27

I\'m using PostgreSQL 9.1 and I have this data structure:

A     B
-------
1     a
1     a
1     b
1     c
1     c
1     c
1     d
2     e
2     e
3条回答
  •  星月不相逢
    2021-02-09 08:16

    This should do the trick:

    SELECT a
         , sum(ab_ct)::int AS ct_total
         , count(*)::int   AS ct_distinct_b
         , array_agg(b || ', ' || ab_ct::text) AS b_arr
    FROM  (
        SELECT a, b, count(*) AS ab_ct
        FROM   tbl
        GROUP  BY a, b
        ORDER  BY a, ab_ct DESC, b  -- append "b" to break ties in the count
        ) t
    GROUP  BY a
    ORDER  BY ct_total DESC;
    

    Returns:

    • ct_total: total count of b per a.
    • ct_distinct_b: count of distinct b per a.
    • b_arr: array of b plus frequency of b, sorted by frequency of b.

    Ordered by total count of b per a.

    Alternatively, you can use an ORDER BY clause within the aggregate call in PostgreSQL 9.0 or later. Like:

    SELECT a
         , sum(ab_ct)::int AS ct_total
         , count(*)::int   AS ct_distinct_b
         , array_agg(b || ', ' || ab_ct::text ORDER BY a, ab_ct DESC, b) AS b_arr
    FROM  (
        SELECT a, b, count(*) AS ab_ct
        FROM   tbl
        GROUP  BY a, b
        ) t
    GROUP  BY a
    ORDER  BY ct_total DESC;

    May be clearer. But it's typically slower. And sorting rows in a subquery works for simple queries like this one. More explanation:

    • How to apply ORDER BY and LIMIT in combination with an aggregate function?

提交回复
热议问题