如何计算sql中聚合中的数字?

时间:2018-06-12 11:25:16

标签: sql postgresql

所以我想聚合共享相同位置的点组,然后计算属于该点的每个类的数量。

我的聚合查询如下:

create table mytable2 as
select count(*) as rows, location, string_agg(distinct class, ', ' order by class)
from mytable
group by location

这样的结果给了我一行例如

 (16, 'Wakanda', 'warrior priest tank')

如何汇总它以显示

(16, 'Wakanda', '10 warrior 5 priest 1 tank')

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您需要两个级别的聚合:

select lc.location,
       string_agg(class || '(' || cnt || ')', ', ' order by cnt desc)
from (select location, class, count(*) as cnt
      from mytable
      group by location, class
     ) lc
group by lc.location;

我把字符串放在我认为更合理的格式中。它看起来像:'战士(10),牧师(5),坦克(1)'。它按频率排序。如果您愿意,您可以(当然)调整语法以获得其他格式。

答案 1 :(得分:1)

示例数据:

create table mytable(location text, class text);
insert into mytable values
('Wakanda', 'warrior'),
('Wakanda', 'warrior'),
('Wakanda', 'priest'),
('Wakanda', 'tank'),
('Wakanda', 'tank'),
('Wakanda', 'warrior');

使用grouping sets.您可以轻松获得一个很好的表格输出:

select location, class, count(*)
from mytable
group by grouping sets ((location), (location, class));

 location |  class  | count 
----------+---------+-------
 Wakanda  | priest  |     1
 Wakanda  | tank    |     2
 Wakanda  | warrior |     3
 Wakanda  |         |     6
(4 rows)

或某个位置的单行,例如:

select
    max(count) as units,
    location, 
    string_agg(class || ': ' || count, ', ') as counts
from (
    select location, class, count(*)
    from mytable
    group by grouping sets ((location), (location, class))
    ) s
group by location;

 units | location |             counts             
-------+----------+--------------------------------
     6 | Wakanda  | priest: 1, tank: 2, warrior: 3
(1 row)