Выбрать главу

итог по всем зарплатам (см. выше):

□ SELECT division_id, SUM(salary)

FROM employees2

GROUP BY R0LLUP(division_id)

ORDER BY division_id;

DIV SUM(SALARY)

BUS 1610000

OPE 1320000

SAL 4936000

SUP 1015000

В столбце d iv is io n _ id для последней строки содержится пустое значение.

Можно использовать функцию GR0UPING() для определения, является

ли значение данного столбца пустым или нет (см. следующий запрос).

GR0UPING() возвращает 0 для строк, имеющих не пустые значения d iv is io n _

id , и 1 для строк с пустыми значениями столбца d iv is io n _ id :

□ SELECT GR0UPING(division_id), division_id, SUM(salary)

FROM employees2

GROUP BY R0LLUP(division_id)

ORDER BY division_id;

GR0UPING(DIVISI0N_ID) DIV SUM(SALARY)

8881000

0 BUS 1610000

0 OPE 1320000

0 SAL 4936000

0 SUP 1015000

1 8881000

216 Гпава 7

Использование CASE для конвертирования возвращаемого

из G R O U P IN G 0 значения

Можно использовать выражение CASE для конвертирования 1 из предыдущего

примера в какое-то осмысленное значение. В следующем примере

CASE используется для конвертирования 1 в строку ‘All divisions’ :

□ SELECT

CASE(GROUPING(division_id)

WHEN 1 THEN ‘All divisions’

ELSE division_id

END AS div,

SUM(salary)

FROM employees2

GROUP BY ROLLUP(division_id)

ORDER BY division_id;

DIV SUM(SALARY)

BUS 1610000 -

OPE 1320000

SAL 4936000

SUP 1015000

A ll divisions 8881000

Использование CASE и G R O U P IN G () для конвертирования

значений нескольких столбцов

В следующем примере идея замены пустых значений расширяется на фразу

ROLLUP, содержащую два столбца - division_id и job_id. Пустые значения

division_id заменяются строкой ‘All divisions’ , а пустые значения job_id -

строкой ‘Alljobs’ :

□ SELECT

CASE GROUPING(divisionJLd)

WHEN 1 THEN ‘All divisions'

ELSE division_id

END AS div,

CASE GR0UPING(job_id)

WHEN 1 THEN ‘All jobs’

ELSE job_id

END AS job,

SUM(salary)

FROM employees2

GROUP BY R0LLUP(division_id, job_id)

ORDER BY division_id, job_id;

DIV JOB SUM(SALARY)

BUS MGR 530000

BUS PRE 800000

BUS W0R 280000

BUS A ll jobs 1610000

Расширенные запросы 217

OPE ENG 245000

OPE MGR 805000

OPE WOR 275000

OPE A ll jobs 1320000

SAL MGR 4446000

SAL WOR 490000

SAL A ll jobs 4936000

SUP MGR 465000

SUP TEC 115000

SUP WOR 435000

SUP A ll jobs 1015000

A ll divisions All jobs 8881000

Использование функции G R O U P IN G () с фразой CUBE

Функцию GR0UPING() можно использовать и в сочетании с фразой CUBE:

□ SELECT

CASE GROUPING(divisiorv id~)

WHEN 1 THEN ‘ A ll divisions’

ELSE division_id

END AS div,

ASE GROUPING(job_id)

WHEN 1 THEN 'A ll jobs’

ELSE job_id

END AS job,

SUM(salary)

FROM employees2

GROUP BY CUBE(division_id, job_id)

ORDER BY division_id, job_id;

DIV JOB SUM(SALARY)

BUS MGR 530000

BUS PRE 800000

BUS WOR 280000

BUS A ll jobs 1610000

OPE ENG 245000

OPE MGR 805000

OPE WOR 275000

OPE All jobs 1320000

SAL MGR 4446000

SAL WOR 490000

SAL A ll jobs 4936000

SUP MGR 465000

SUP TEC 115000

SUP WOR 435000

SUP A ll jobs 1015000

218 Глава 7

All d iv is io n s ENG 245000

A ll d iv is io n s MGR 6246000

A ll d iv is io n s PRE 800000

A ll d iv is io n s TEC 115000

A ll d iv is io n s W0R 1475000

A ll d iv is io n s A ll jobs 8881000

Использование фразы GROUPING SETS

Фраза GROUPING SETS используется, когда нужно получить только строки с

промежуточными суммами. В следующем примере фраза GROUPING SETS используется

для получения промежуточных сумм для зарплат в разбивке по

d iv is io n _ id H jo b _ id :

□ SELECT division_id, job_id, SUM(salary)

FROM employees2

GROUP BY GROUPING SETS(division_id, job_id)

ORDER BY division_id, job_id;

DIV JOB SUM(SALARY)

BUS 1610000

OPE 1320000

SAL 4936000

SUP 1015000

ENG 245000

MGR 6246000

PRE 800000

TEC 115000

W0R 1475000

Обратите внимание: возвращены только строки с промежуточными

суммами зарплат по d iv is io n _ id и j ob_id, а общий итог по всем группам не

возвращается. В следующем разделе вы узнаете, как с помощью функции

GR0UPING_ID() наряду с промежуточными итогами можно получить и общий

итог.

Подсказка Оператор GROUPING SETS обычно является более производительным по сравнению

с CUBE. Поэтому рекомендуется использовать GROUPING SETS вместо CUBE там, где это возможно.

Использование функции GROUPING JD()

Можно использовать функцию GR0UPING_ID() для фильтрации строк с

использованием фразы HAVING, чтобы исключить строки, не содержащие

промежуточных итогов или общих итогов. Функция GR0UPING_ID()

принимает один или несколько столбцов и возвращает десятичный эквивалент

битового вектора GROUPING. Этот вектор вычисляется путем

комбинации результатов вызова функции GROUPING( ) для каждого столбца

по порядку.

Расширенные запросы 219

Вычисление битового вектора G R O U P IN G

В разделе «Использование функции GR0UPINGO» было показано, что

GROUPING( ) возвращает 1, если значение столбца пустое, и 0, если соответствующее

значение не пустое. Например:

■ Если оба столбца d iv is io n _ id и job^id содержат непустые значения,