Как агрегировать сумму поля в значение string_Aggregated Postgres - PullRequest
0 голосов
/ 17 сентября 2018

Приведенный ниже запрос показывает мне список студентов с их базовой информацией.

Я хотел бы собрать сумму мальчиков и девочек, не отображая для них отдельные столбцы.Поэтому я создал 2 столбца и взял их итоговую сумму и отобразил ее в последнем ряду.

Часть 1

with ext as (
select s.studentid as SID,p.surname AS Lastname,
        p.firstname AS Firstname,
        p.sex AS Gender,
        p.birthdate AS BDate,
        ctf.name as Nation,
      SUM(CASE WHEN p.sex = 'MALE' THEN 1 ELSE 0 END) AS BoyCount,
      SUM(CASE WHEN p.sex = 'FEMALE' THEN 1 ELSE 0 END) AS GirlCount
from students s
        join pupil p on p.id = s.pupilid
        join pupilnation pn on pn.pupilid = p.id
        join country ctf on ctf.id = pn.coutnryid
        ...   
group by s.studentid, p.surname, p.firstname,p.sex,p.birthdate,ctf.name
)

Часть2

select SID,Lastname,Firstname,Gender,BDate,Nation
from ext
union all
select 'Students: ' || cast(count(SID) as varchar(6)), 
    null as Lastname, 
    null as Firstname,
    'Boys: ' || cast(sum(boycount) as varchar(6)) || '   Girls: ' || cast(sum(girlcount) as varchar(6)),
    null as Bdate,
    string_agg(distinct Nation,',')

Результаты

SID     Firstname   Gender  Bdate       Nation
723785  Saria       FEMALE  20.01.2012  France
45949   Wenzel      MALE    08.11.2011  Germany
3373    Constantin  MALE    19.03.2006  Germany
727578  Laurin      MALE    08.04.2012  Germany
157     Valerian    MALE    15.01.2008  UK
595959  Attila      MALE    08.06.2012  USA
4172    Sophie      FEMALE  01.11.2004  France
693465  Ibrahim     MALE    16.05.2011  Belgium
…                   
…                   
12 Students         8 Males 4 Females   Germany, France, UK, US, Ughanda

Ожидаемые результаты

Я хочу, чтобы агрегированная итоговая сумма каждой нации была присоединена к ее строке в агрегации строк.Будет ли это возможно, как показано ниже?Например, Германия: 5, Франция: 3, Великобритания: 2, США: 1, Уганда: 1

SID     Firstname   Gender  Bdate       Nation
723785  Saria       FEMALE  20.01.2012  France
45949   Wenzel      MALE    08.11.2011  Germany
…                   
…                       
12 Students         8 Males 4 Females   Germany: 5, France: 3, UK: 2, US: 1, Ughanda: 1

1 Ответ

0 голосов
/ 17 сентября 2018

вы можете написать подзапрос count на Nation в select, затем использовать функцию string_agg.

select SID,Lastname,Firstname,Gender,BDate,Nation
from ext
union all
select 'Students: ' || cast(count(SID) as varchar(6)), 
    null as Lastname, 
    null as Firstname,
    'Boys: ' || cast(sum(boycount) as varchar(6)) || '   Girls: ' || cast(sum(girlcount) as varchar(6)),
    null as Bdate,
    (
        select  string_agg(cnt , ', ') from 
        (
          SELECT Nation||':'||COUNT(*) cnt
          FROM ext
          GROUP BY Nation
        ) t1
    )
FROM ext

или вы можете использовать CROSS JOIN, чтобы сделать его

SELECT 
    'Students: ' || cast(totalCnt as varchar(6)), 
    null as Lastname, 
    null as Firstname,
    'Boys: ' || cast(boyCnt as varchar(6)) || '   Girls: ' || cast(girlCnt as varchar(6)),
    null as Bdate,
    v.Nation
FROM (
    select  
       sum(boycount) boyCnt,
       sum(girlcount) girlCnt,
       count(SID) totalCnt
    FROM ext
) t1 
CROSS JOIN (
  select string_agg(cnt , ', ') Nation from 
  (
    SELECT Nation||':'||COUNT(*) cnt
    FROM ext
    GROUP BY Nation
  ) t1
) v
...