SELECT
WIDTH_BUCKET(amount, 0, 5000, 5) AS bucket,
COUNT(*) AS orders
FROM orders
GROUP BY bucket
ORDER BY bucket;
Результат:
bucket | orders
-------+-------
1 | 412
2 | 233
6 | 7
SELECT
WIDTH_BUCKET(age, 18, 68, 5) AS age_group,
COUNT(*) AS users
FROM users
GROUP BY age_group
ORDER BY age_group;
Результат:
age_group | users
----------+------
1 | 140
2 | 201
3 | 98
SELECT
WIDTH_BUCKET(-50, 0, 100, 4) AS below,
WIDTH_BUCKET(150, 0, 100, 4) AS above;
Результат:
below | above
------+------
0 | 5
Порешать SQL-задачи в тренажёре →
Спрашивают при построении гистограмм и распределений (суммы чеков, возраст, latency) в паре с GROUP BY. Частый follow-up — как воспроизвести бакетирование без WIDTH_BUCKET в MySQL или SQLite.
Нет, WIDTH_BUCKET поддерживают PostgreSQL и Oracle, а в MySQL и SQLite её нет. Там равные бакеты считают арифметикой: FLOOR((x - low) / step) + 1, где step = (high - low) / count, либо через набор CASE WHEN с явными границами. Значения вне диапазона нужно обрабатывать самому.
Это служебные корзины для значений вне заданного диапазона. Всё, что меньше low, попадает в 0, а всё, что больше или равно high, — в count+1. Так WIDTH_BUCKET не теряет выбросы; если они не нужны, отфильтруй их в WHERE или объедини крайние корзины.
Для произвольных границ в PostgreSQL используй форму с массивом: WIDTH_BUCKET(operand, ARRAY[100, 500, 1000, 5000]). Массив должен быть отсортирован по возрастанию, а функция вернёт номер интервала, в который попал operand. Это удобно для бизнес-порогов, которые не равны по ширине.
COALESCE · NULLIF · CASE WHEN · STRING_AGG · COUNT · SUM OVER
Открыть SQL-тренажёр (565 задач) →