итог по всем зарплатам (см. выше):
□ 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 содержат непустые значения,