Trino: LATERAL VIEW EXPLODE in presto
Ты пришёл из мира Hive или Spark, где `LATERAL VIEW EXPLODE` — это как дыхание. Хочешь развернуть мапу в строки, отфильтровать что-то и поехать дальше. Запускае
Ты пришёл из мира Hive или Spark, где LATERAL VIEW EXPLODE — это как дыхание. Хочешь развернуть мапу в строки, отфильтровать что-то и поехать дальше. Запускаешь свой привычный запрос в Trino (он же PrestoSQL), а в ответ — холодный и безэмоциональный SYNTAX_ERROR.
Ты начинаешь гуглить. Старые форумы шепчут про UNNEST. Документация Trino молчаливо кивает. Всё верно, здесь такого оператора нет. Но есть кое-что мощнее и идиоматичнее.
Магия UNNEST вместо взрыва
Забудь про EXPLODE. В Trino есть UNNEST. Это не просто замена, это более чистый и логичный способ работать с коллекциями. Он превращает мапу или массив в набор строк, с которым можно джойнить.
Твоя задача — развернуть вложенную структуру map<string, map<string,string>>. Цель — добраться до внутренних short имён, чтобы по ним фильтровать.
Вот как это выглядит на практике. Берём исходный пример таблицы и превращаем его в рабочий запрос.
SELECT
id.id,
exploded_key,
exploded_value['short'] AS name
FROM id
CROSS JOIN UNNEST(names) AS t(exploded_key, exploded_value)
WHERE exploded_value['short'] LIKE '%Milan%'
Разберём магию по косточкам. Ключевая строчка — это CROSS JOIN UNNEST(names) AS t(exploded_key, exploded_value). Она делает следующее: берёт твою колонку names (ту самую сложную мапу) и для каждой строки исходной таблицы создаёт несколько новых строк.
В каждой новой строке будут два поля: exploded_key (это твой внешний ключ, например, 3081, 2057) и exploded_value (это внутренняя мапа {short=Abbazia 81427 - Milan}).
Дальше мы просто обращаемся к внутреннему значению через exploded_value['short']. Всё. Теперь можно спокойно использовать WHERE, GROUP BY или что угодно.
Почему это лучше старого подхода
CROSS JOIN UNNEST — это не костыль, а полноценный реляционный оператор. Он явно показывает, что происходит увеличение кардинальности данных. Его логику проще читать и оптимизировать движку.
Не пытайся искать флаги совместимости с Hive. Иди своим путём. Выучи этот паттерн: FROM таблица CROSS JOIN UNNEST(твоя_колонка_мапа_или_массив) AS псевдоним(ключ, значение).
Подход работает с любыми вложенными структурами — массивами, мапами, их комбинациями. Нужно развернуть мапу из мап? Без проблем, как в твоём случае. Нужно развернуть массив, а потом каждый его элемент (который тоже мапа)? Цепляй ещё один UNNEST.
Финал
Итак, алгоритм прост. Выброси LATERAL VIEW EXPLODE из головы. Вспоминаешь SQL-стандарт. Пишешь CROSS JOIN UNNEST. Джойнишь, фильтруешь, агрегируешь. Всё как с обычными таблицами, потому что теперь это и есть обычные строки.
И да, если в процессе получил SYNTAX_ERROR — проверь, не забыл ли запятую перед UNNEST. Такое бывает.