Перейти к основному содержанию

Введение

В ClickHouse нет оператора PIVOT, но аналогичного поведения можно добиться с помощью комбинаторов агрегатных функций, в частности комбинаторов с суффиксом -Map. В этой статье мы разберем, как это сделать. Ниже также доступно видео с тем же материалом:

Что такое комбинаторы агрегатных функций

Начнем с простого примера. Мы будем использовать clickhouse-local, который можно запустить следующей командой:
Следующий запрос вызывает функцию sumMap, которая принимает объект типа Map и суммирует значения для каждого ключа:
Это не самый интересный пример, поскольку он возвращает то же значение Map, которое мы передали. Теперь вызовем sumMap для нескольких строк со значениями Map;
Ключ ClickHouse присутствовал в обеих строках, и его значения были суммированы. Ключ ClickBench присутствовал только в одной строке, поэтому суммируется только одно значение — в результате возвращается оно же! Мы также можем использовать maxMap, чтобы найти максимальные значения для каждого ключа:
Или можно использовать avgMap, чтобы вычислить среднее значение по каждому ключу:
Надеюсь, теперь вы лучше представляете, как работают эти комбинаторы функций.

Практическое применение: набор данных о ценах на жильё в Великобритании

Теперь применим их к более крупному набору данных в Песочнице ClickHouse. Мы можем подключиться к песочнице с помощью clickhouse-client:
Мы будем выполнять запросы к таблице uk_price_paid, поэтому давайте сначала посмотрим, какие данные в ней хранятся:
Как видно выше, таблица содержит различные поля, связанные с продажей недвижимости в Великобритании.

Группировка и агрегация по десятилетиям

Давайте вычислим медианные цены по графствам для каждого десятилетия в наборе данных:

Фильтрация результатов

Мы можем отфильтровать результаты так, чтобы в них остались только данные за 2010 год и позже:

Объединение нескольких агрегаций

Если мы хотим найти максимальную цену для каждого десятилетия, это можно сделать с помощью функции maxMap, которую мы уже видели ранее:

Применение функций к значениям Map

В качестве альтернативы можно вычислить среднюю цену с помощью avgMap. У этих значений слишком много знаков после запятой, но это можно исправить, применив функцию mapApply, чтобы вызвать функцию floor для каждого значения в Map:

Гибкая группировка: графства, районы и почтовые индексы

Давайте попробуем выполнить группировку по другим полям. На этот раз мы вычислим медианную цену за десятилетие с группировкой по графству и району:
Мы также могли бы выполнить группировку по году, а затем объединить postcode1 и postcode2 в map:
Последнее изменение 12 июня 2026 г.