🔥 Live Coding: работа с массивами в ClickHouse Задача:
Есть таблица orders:
order_id user_id products Array(String)
Пример:
['apple', 'banana', 'milk'] ['apple'] []
Нужно:
👉 посчитать, сколько заказов содержат товар 'apple' 👉 и развернуть массив товаров в строки
⚠️ Важно:
• массив может быть пустым • в массиве может быть несколько товаров • один товар может повторяться
📊 На выходе хотим получить: количество заказов с apple список товаров построчно 🧪 Решение
1. Проверка наличия элемента в массиве
select count() from orders where has(products, 'apple')
2. Разворачивание массива
select order_id, arrayJoin(products) as product from orders 🧠 Как здесь думаем:
has()
👉 проверяет: есть ли элемент в массиве 👉 возвращает 1 / 0
Важно: это не join, а векторная операция внутри строки → работает очень быстро
arrayJoin()
👉 превращает массив в несколько строк
['apple', 'banana'] ↓ apple banana
👉 фактически делает “размножение строк”
⚠️ Где можно ошибиться:
1. Забыть про дубли
arrayJoin(products)
❗️ если в массиве:
['apple', 'apple']
👉 получим 2 строки
2. Делать join вместо has()
❌ лишняя нагрузка
👉 has() быстрее, потому что не требует разворота массива
3. Не учитывать пустые массивы
arrayJoin(products)
👉 пустые массивы просто исчезнут из результата
💡 Полезные функции ClickHouse arrayExists(x -> x = 'apple', products) arrayFilter(x -> x != 'apple', products) arrayMap(x -> lower(x), products) length(products)
👉 это уже уровень “работа с массивом как с мини-таблицей”
🚀 ClickHouse-нюанс
Массивы в ClickHouse — это не просто тип данных
👉 это способ:
хранить события хранить списки атрибутов делать быстрые проверки без join
Часто заменяют отдельные таблицы и связи
🎯 Вывод:
Массивы в ClickHouse = мощный инструмент
Главные паттерны:
has() → проверить наличие arrayJoin() → развернуть array* функции → обработать внутри строки
👉 сначала думаем: можно ли решить без JOIN и только потом идём в классическую модель