10

我正在使用 PostgreSQL 9.1,我有这个数据结构:

A     B
-------
1     a
1     a
1     b
1     c
1     c
1     c
1     d
2     e
2     e

我需要一个产生这个结果的查询:

1    4     {{c,3},{a,2},{b,1},{d,1}}
2    1     {{e,2}}

A=1,总共 4 行,A=1,部分计数(3 行有 c 值,2 行有值,......)

  • “A”列的不同值
  • 与“A”值相关的所有行数
  • 数组包含与“A”值相关的所有元素以及自身的相对计数

数组所需的排序基于每个组的计数(如示例 3、2、1、1)。

4

3 回答 3

13

这应该可以解决问题:

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;

回报:

  • ct_totalb:每人的总数a
  • ct_distinct_bb:每个不同的计数a
  • b_arrb: 的加频率数组b,按 的频率排序b

b按per的总数排序a

或者,您可以在 PostgreSQL 9.0 或更高版本的聚合调用中使用ORDER BY子句。像:

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;

可能会更清楚。但它通常较慢。子查询中的行排序适用于像这样的简单查询。更多解释:

于 2012-03-20T23:13:19.317 回答
5

也许我错过了一些东西,但这应该这样做:

SELECT a, 
       count(*) as cnt,
       array_agg(b) as all_values
FROM your_table
GROUP BY a
于 2012-03-20T22:41:57.470 回答
4

这就是你需要的:

SELECT A, COUNT(*), array_agg(b)
FROM YourTable
GROUP BY A
于 2012-03-20T22:43:08.213 回答