Оператор CASE в предложении GROUP BY
Пусть теперь мы хотим получить количество компьютеров, подходящих по RAM к каждому типу операционных систем. Тогда мы можем написать следующий запрос:
SELECT
CASE
WHEN ram < 64
THEN 'W95'
WHEN ram < 128
THEN 'W98'
ELSE 'W2k'
END Type,
COUNT(*) Qty
FROM PC
GROUP BY
CASE
WHEN ram < 64
THEN 'W95'
WHEN ram < 128
THEN 'W98'
ELSE 'W2k'
END;| [[ column ]] |
|---|
| NULL [[ value ]] |
В результате выполнения запроса получим:
| Type | Qty |
|---|---|
| W2k | 6 |
| W95 | 3 |
| W98 | 3 |
Здесь мы дублируем оператор CASE в предложении SELECT, чтобы получить столбец с наименованием операционной системы.
Использование оператора CASE в предложении GROUP BY позволяет в рамках одного запроса выполнять группировку по разному числу столбцов. Рассмотрим, например, следующую задачу.
Сначала для сравнения приведем результаты группировки по одному (speed) и двум столбцам (speed, hd) соответственно.
select speed,max(hd) max_hd, avg(price) avg_price
from pc
group by speed;| [[ column ]] |
|---|
| NULL [[ value ]] |
| speed | max_hd | avg_price |
|---|---|---|
| 450 | 10 | 350 |
| 500 | 10 | 487.5 |
| 600 | 14 | 850 |
| 750 | 20 | 900 |
| 800 | 20 | 970 |
| 900 | 40 | 980 |
select speed, hd max_hd, avg(price) avg_price
from pc
group by speed, hd
order by speed;| [[ column ]] |
|---|
| NULL [[ value ]] |
| speed | max_hd | avg_price |
|---|---|---|
| 450 | 8 | 350 |
| 450 | 10 | 350 |
| 500 | 5 | 600 |
| 500 | 10 | 375 |
| 600 | 8 | 850 |
| 600 | 14 | 850 |
| 750 | 14 | 850 |
| 750 | 20 | 950 |
| 800 | 20 | 970 |
| 900 | 40 | 980 |
Поскольку в каждой группе значения hd совпадают, можно max(hd) и hd использовать равноправно.
Теперь дадим решение нашей задачи:
select speed, max(hd) max_hd, avg(price) avg_price
from pc
group by speed,
case
when speed >= 600
then hd
else speed
end
order by speed;| [[ column ]] |
|---|
| NULL [[ value ]] |
| speed | max_hd | avg_price |
|---|---|---|
| 450 | 10 | 350 |
| 500 | 10 | 487.5 |
| 600 | 8 | 850 |
| 600 | 14 | 850 |
| 750 | 14 | 850 |
| 750 | 20 | 950 |
| 800 | 20 | 970 |
| 900 | 40 | 980 |
Когда speed >= 600, выполняется группировка по столбцам speed, hd. В противном случае группировка выглядит так:
GROUP BY speed, speedчто эквивалентно группировке одному столбцу. Кстати, оператор CASE в последнем решении можно было написать без ELSE:
select speed, max(hd) max_hd, avg(price) avg_price
from pc
group by speed,
case
when speed >= 600
then hd
end
order by speed;| [[ column ]] |
|---|
| NULL [[ value ]] |
Хотя явная группировка - GROUP BY speed, NULL - будет вызывать ошибку.