Раздел 38 · ClickHouse и аналитические базы

Агрегации и аналитические функции

junior~15 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Данные залиты, теперь ради чего всё затевалось: отчёты. GROUP BY, count, sum, avg работают в ClickHouse так же, как в PostgreSQL, их мы разбирали в разделе про SQL. В этом уроке про то, чего в PostgreSQL нет или что там неудобно: приблизительный подсчёт уникальных, квантили одной функцией, «значение при максимуме», топы внутри групп.

Группировка по времени

Дашборд почти всегда рисует время по оси: заказы по часам, выручка по дням. Для этого в ClickHouse есть семейство функций, которые округляют время вниз:

Функция2026-06-30 09:41:05 превращается в
toStartOfHour(ts)2026-06-30 09:00:00
toStartOfDay(ts)2026-06-30 00:00:00
toDate(ts)2026-06-30
toMonday(ts)2026-06-29
toStartOfMonth(ts)2026-06-01
toHour(ts)9
toDayOfWeek(ts)2 (вторник, неделя с понедельника)

Группируешь по такой функции, и время превращается в ось графика:

SELECT toDate(created_at) AS day, count() AS orders
FROM orders
GROUP BY day
ORDER BY day;

Обрати внимание: в ClickHouse можно группировать и сортировать по псевдониму из SELECT, писать выражение второй раз не нужно.

Сколько уникальных

«Сколько разных клиентов сделали заказ в июне?» В PostgreSQL это count(DISTINCT customer_id). На миллиардах строк точный подсчёт уникальных тяжёлый: базе надо помнить каждое встреченное значение.

ClickHouse предлагает два варианта:

  • uniqExact(customer_id) считает точно, как count(DISTINCT ...);
  • uniq(customer_id) считает приблизительно, с ошибкой обычно меньше процента, зато быстрее и почти без памяти.

Для дашбордов, где «12 345 или 12 380 пользователей» не важно, берут uniq. Для денег и отчётности берут uniqExact.

Квантили

Среднее время доставки обманывает: пара заказов, застрявших на три часа, тянет среднее вверх. Честнее смотреть квантили: медиану и 90-й перцентиль.

SELECT
    median(price_rub) AS p50,
    quantile(0.9)(price_rub) AS p90,
    quantiles(0.5, 0.9, 0.99)(price_rub) AS all_three
FROM orders;

Заметь непривычный синтаксис quantile(0.9)(price_rub). Первые скобки это параметры функции, вторые это колонка. quantile тоже приблизительный: он считает по выборке. Точный вариант называется quantileExact.

урок из курса

Урок из курса «ClickHouse и аналитические базы». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.