2016-04-27 12 views
1

Ich habe eine Tabelle wie folgt.String Aggregat Gruppe und auf einen Wert

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

Ich habe eine Abfrage wie folgt.

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

Mein Ergebnis ist

| 1 | Jane-John-Tom-Bob | 

aber ich möchte mein Geschlecht Zahl zählen auch bedeuten, i in der ersten Gruppe (Cass 1) Ich brauche eine Spalte wie 1 F + 3 M

Meine Anfrage ist so etwas und ich möchte es in 1 Gruppe von verwenden.

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

'array_to_string (array_agg (Name), '- ':: Text)' kann 'string_agg (Name,' -') vereinfacht werden' –

Antwort

2

Sie können tun, dass mit einem gefilterten Aggregat:

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; 

Wenn Sie auf einem älteren Postgres Version sind, müssen Sie

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

mit

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

(und das gleiche für 'M')

+0

Danke für die Hilfe. Das ist großartig. Für den weiteren Gebrauch, wenn ich die Werte nicht kenne, aber ich kenne eine Spalte, die ich für die Gruppe verwenden kann, wie kann ich es im Filter verwenden? Vielleicht kann ich mehr als 10 Filterwerte verwenden. – lokmancetin

+0

@lokmancetin: Entschuldigung, ich verstehe dich nicht. Die Spalte, die Sie gruppieren, hat nichts mit der Spalte zu tun, in der Sie das gefilterte Aggregat auf –

+0

anwenden. In Ihrer Antwort sind die Filterwerte wie F und M üblich. Einfach. Aber was ist, wenn die Filterwerte mehr als 50 sind, und diese 50 Werte sind auch in der Spalte in dieser aktuellen Tabelle. Ich kann seine Werte nach Gruppen gruppieren, und ich möchte diese gruppierten Werte im Filteraggregat verwenden. – lokmancetin

0

Es gibt auch eine andere Lösung ohne Filter Aggregat mit

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 

Ergebnis;

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