Идентификация сгруппированных данных

Функция GROUPING предназначена для различения сгруппированных данных.

Спецификация
   
< идентификация сгруппированных данных >::=
Синтаксические правила
  1. Функция используется только совместно с предложением GROUP BY.

  2. Функция возвращает уровень агрегирования, соответствующий каждой записи результирующей выборки данных.

  3. Элементами < значимого выражения > могут быть:

    • < имя столбца > (или < псевдоним столбца >);

    • < агрегатная функция >;

    • < спецификация типа >;

    • < спецификация значения по условию >.

  4. < Значимые выражения > должны ссылаться на группируемый элемент таблицы.

  5. < Значимые выражения > не могут быть константами.

Например, запрос:

select 1, order_year, grouping(1,order_year), count(*) from order_details
 group by rollup(1, order_year);

является синтаксически неправильным.

А запрос

select cast 1 as int, order_year, grouping(cast 1 as int,order_year), count(*) 
  from order_details
 group by rollup(cast 1 as int, order_year);

является синтаксически правильным.

Общие правила
  1. Функция GROUPING возвращает 0, если NULL-значение столбца взято из фактических данных, и 1, если NULL-значение столбца сформировано операцией ROLLUP или CUBE. В SELECT-запросе можно использовать функцию GROUPING, чтобы заменить любое формируемое NULL-значение нужной записью (например «Итого:»). Так как NULL-значения из фактических данных указывают на то, что значение данных неизвестно, в SELECT-запросе можно также указать возвращение записи 'Неизвестно' вместо любых NULL-значений из фактических данных.

Примеры
  1. create or replace table test( a int, b int, c int, d int, e int, f int);
    insert into test values (1,10,100,1000,10000,100000);
    insert into test values (1,11,101,1001,10001,100001);
    insert into test values (2,20,200,2000,20000,200000);
    insert into test values (3,30,300,3000,30000,300000);
    insert into test values (3,31,301,3001,30001,300001);
    
    select a, b, c, count(*), grouping(a,b,c) from test group by (a,rollup(b,c));
     A        B        C
     -        -        -
    |       1|      10|     100|       1|                0|
    |       1|      11|     101|       1|                0|
    |       2|      20|     200|       1|                0|
    |       3|      30|     300|       1|                0|
    |       3|      31|     301|       1|                0|
    |       1|      10|        |       1|                1|
    |       1|      11|        |       1|                1|
    |       2|      20|        |       1|                1|
    |       3|      30|        |       1|                1|
    |       3|      31|        |       1|                1|
    |       1|        |        |       2|                3|
    |       2|        |        |       1|                3|
    |       3|        |        |       2|                3|
  2. SELECT CASE GROUPING(make) when 0 THEN make else 'Всего: ' END AS make,
           CASE GROUPING(COLOR) when 0 THEN color else 'Итого по фирме: ' END AS color,
           count(*)
      FROM auto
     GROUP BY GROUPING SETS ((make, color), (make),(color));
    
     MAKE             COLOR
     ----             -----
    | ALPINE         |BLACK           |            1|
    |ALPINE          |GREY            |            3|
    |ALPINE          |WHITE           |            3|
    |AMERICAN MOTORS |BLACK           |           23|
    |AMERICAN MOTORS |BLUE            |           11|
    …
    |ALPINE          |Итого по фирме: |            7|
    |AMERICAN MOTORS |Итого по фирме: |           91|
    |BMW             |Итого по фирме: |           10|
    |CHRYSLER        |Итого по фирме: |          168|
    |CITROEN         |Итого по фирме: |            7|
    |DATSUN          |Итого по фирме: |           10|
    …
    |Всего:          |BLACK           |          262|
    |Всего:          |BLUE            |          108|
    |Всего:          |BROWN           |           46|
    …