Оператор 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 - будет вызывать ошибку.