字符串聚合组和计数值

时间:2016-04-27 08:12:31

标签: sql database postgresql aggregate-functions

我有这样的表格。

 | table                        |
 | class_id| name    | gender   |
 +---------+---------+----------+ 
 |       1 | Jane    |     F    |
 |       1 | John    |     M    |
 |       1 | Tom     |     M    |
 |       1 | Bob     |     M    |
 |       2 | Jack    |     M    |
 |       2 | Kate    |     F    |

我有这样的查询。

select id, array_to_string(array_agg(name), ' - '::text) as name_list from table
group by class_id

我的结果是

 | 1 | Jane-John-Tom-Bob |

但是我想计算我的性别数量,我的意思是在第一组(cass 1)我需要一个像1 F + 3 M

的列

我的请求是这样的,我想在1组中使用它。

 | 1 | Jane-John-Tom-Bob |1F + 3M

2 个答案:

答案 0 :(得分:2)

您可以使用过滤后的聚合来执行此操作:

select id, 
       string_agg(name), ' - ') as name_list, 
       concat( 
            count(*) filter (where gender = 'F'), 
            'F + ', 
            count(*) filter (where gender = 'M'), 
            'M') as gender_count
from table
group by class_id;

如果您使用较旧的Postgres版本,则需要替换

count(*) filter (where gender = 'F')

count(case when gender = 'F' then 1 end) 

(同样适用于' M')

答案 1 :(得分:0)

还有另一种不使用过滤器聚合的解决方案

select tt.class_id, string_agg ( t,  ','::text) as gender, string_agg(distinct y,','::text) as name

from 

(

select class_id, count(gender)::text|| string_agg( distinct  gender, ','   ) as  t
       from string_test
group by class_id , gender

) tt , 

(
select class_id, string_agg( distinct name::text, ','::text ) as y
    from string_test
group by class_id
) yy
where tt.class_id=yy.class_id

group by tt.class_id

结果;

+==========+========+===================+
| class_id | gender | name              |
+==========+========+===================+
| 1        | 1F,3M  | Bob,Jane,John,Tom |
+----------+--------+-------------------+
| 2        | 1F,1M  | Jack,Kate         |
+==========+========+===================+