postgresql, именованные наборы группировок?

Есть ли способ назвать наборы группировки? Для каждого набора группировки (явно определенного или сгенерированного с помощью накопительного пакета или куба согласно https://www.postgresql.org/docs/devel/static/queries-table-expressions.html) я хотел бы как-то указать имя в столбец результата. Вот уродливая мгновенная демонстрация того, что я пытаюсь сделать, с именем, являющимся просто списком сгруппированных столбцов:

select *, array_to_string(array_remove(array[case when "A" is null then null else 'A' end,
                                             case when "B" is null then null else 'B' end,
                                             case when "C" is null then null else 'C' end
                                            ],null),',') as grouping_set
from (values  ('a','b','c'),
              ('aa','bb','cc'),
              ('aaa',null,'ccc')) as foo("A","B","C")
group by rollup(1,2,3);


  A  | B  |  C  | grouping_set
-----+----+-----+--------------
 a   | b  | c   | A,B,C
 a   | b  |     | A,B
 a   |    |     | A
 aa  | bb | cc  | A,B,C
 aa  | bb |     | A,B
 aa  |    |     | A
 aaa |    | ccc | A,C   <--------- should be A,B,C
 aaa |    |     | A     <--------- should be A,B
 aaa |    |     | A 
     |    |     |

Но обратите внимание, что есть проблема с двумя строками, помеченными стрелками: обе они включают столбец B в группировку, но не в имя, потому что в этих группах B пусто.

Есть идеи или лучшие способы обойти это?

2 ответа

Решение
SELECT "A", "B", "C",
       CASE GROUPING("A", "B", "C")
          WHEN 0 THEN 'A,B,C'
          WHEN 1 THEN 'A,B'
          WHEN 3 THEN 'A'
          ELSE ''
       END AS grouping_set
FROM (VALUES ('a','b','c'),
             ('aa','bb','cc'),
             ('aaa',null,'ccc')
     ) AS foo("A","B","C")
GROUP BY ROLLUP(1,2,3);

Соответствующая документация по группировке наборов согласно ответу Clodoaldo Neto.

Группировка операций

Операции группировки используются вместе с наборами группировки (см. Раздел 7.2.4) для различения строк результатов. Аргументы операции GROUPING фактически не оцениваются, но они должны точно соответствовать выражениям, приведенным в предложении GROUP BY соответствующего уровня запроса. Биты назначаются с самым правым аргументом, являющимся младшим значащим битом; каждый бит равен 0, если соответствующее выражение включено в критерии группировки набора группировки, генерирующего строку результата, и 1, если это не так.

select *, grouping("A","B","C") as grouping_set
from (values
    ('a','b','c'),
    ('aa','bb','cc'),
    ('aaa',null,'ccc')
) as foo("A","B","C")
group by rollup(1,2,3);
  A  | B  |  C  | grouping_set 
-----+----+-----+--------------
 a   | b  | c   |            0
 a   | b  |     |            1
 a   |    |     |            3
 aa  | bb | cc  |            0
 aa  | bb |     |            1
 aa  |    |     |            3
 aaa |    | ccc |            0
 aaa |    |     |            1
 aaa |    |     |            3
     |    |     |            7
Другие вопросы по тегам