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

К безошибочному UNION ALL

· 3 мин. чтения
David Krevitt

Это неблагодарная, но необходимая задача. В SQL часто нужно объединять (UNION ALL) две или более таблицы вертикально, чтобы объединить их значения.

Предположим, нам нужно объединить 3 таблицы: веб-трафик, расходы на рекламу и данные о продажах, чтобы получить полное представление о стоимости привлечения (CPA).

В конечном итоге, мы хотели бы агрегировать данные с детализацией по дате, URL целевой страницы, кампании и каналу — поэтому, как бы мы ни объединяли 3 таблицы, мы захотим обернуть это во внешний запрос с GROUP BY, чтобы уменьшить .

Для этого мы могли бы сделать несколько вещей:

  • FULL OUTER JOIN: возвращает все значения + объединяет там, где есть совпадение по дате / целевой странице / кампании / каналу

  • UNION: объединяет все значения вертикально + удаляет дубликаты, чтобы вернуть уникальные значения

  • UNION ALL: объединяет все значения вертикально, без логики сопоставления

Предположим, что данные были очищены от дубликатов на более низком уровне (в стейджинговой модели для исходных данных), поэтому здесь удаление дубликатов не требуется.

С точки зрения производительности, UNION ALL всегда будет более производительным, чем FULL OUTER JOIN, так как нет операции сопоставления, UNION ALL просто добавляет таблицы.

Задача заполнения значений null в UNION ALL

Часто при выполнении UNION ALL у таблиц будут несовпадающие столбцы: в таблице веб-трафика не будет значений дохода, а в данных о продажах не будет значений сессий.

Чтобы завершить объединение, мы должны заполнить эти столбцы как null или 0 в нашем запросе, чтобы объединение прошло успешно:

select
date,
landing_page_url,
campaign,
channel,
sessions,
pageviews,
time_on_site,
null as orders,
null as customers,
null as revenue
from sessions

union all

select
date,
landing_page_url,
campaign,
channel,
null as sessions,
null as pageviews,
null as time_on_site,
orders,
customers,
revenue
from sales

Без этих значений null мы получим неприятную ошибку:

Запросы в UNION ALL имеют несовпадающее количество столбцов; запрос 1 имеет 10 столбцов, запрос 2 имеет 12 столбцов

Как вы можете себе представить, это становится очень болезненным, когда мы хотим добавить новый столбец в наши UNION — мы должны добавить столбец как значение null в каждое выражение запроса в стеке UNION ALL.

Встречайте макрос union_relations в dbt

dbt позволяет вам писать макросы в Jinja, чтобы автоматизировать эту задачу.

Макрос union_relations в пакете dbt_utils полностью освобождает нас от необходимости заполнять null или 0 для каждого столбца, который не существует в других таблицах, которые мы объединяем.

С помощью 3 строк кода мы можем достичь того, что ранее требовало десятков:

{{ dbt_utils.union_relations(

relations=[ref('sessions'), ref('sales'), ref('ads')

) }}

Когда dbt выполняется (либо локально в командной строке, в dbt Cloud, или где бы вы ни решили его развернуть), макрос union_relations генерирует точно такой же SQL, как мы писали вручную.

Вы можете увидеть в исходном коде макроса, что он находит каждый столбец в таблицах, которые вы объединяете, проверяет, существуют ли эти столбцы в других таблицах, и если нет, заполняет их строкой null as ,.

Новичок в dbt? Ознакомьтесь с введением в dbt для получения дополнительной информации о dbt и рабочем процессе аналитической инженерии, который он поддерживает.

Кратко: dbt позволяет специалистам по данным писать код как инженеры-программисты, что в данном случае означает не повторять себя без необходимости.

Для меня магия макроса union_relations очевидна — он позволяет мне значительно сэкономить время на выполнении задачи заполнения значений null в выражении UNION ALL.

Если вам интересно углубиться в то, как работают макросы dbt, макрос union_relations использует несколько управляющих структур программирования: циклы for и условные операторы if — благодаря поддержке dbt шаблонов Jinja, мы теперь можем использовать эти управляющие структуры, чтобы писать SQL, который пишет сам себя.

Comments

Loading

Missed Coalesce 2024?

Catch up on Coalesce 2024 and register to access a select number of on-demand sessions.

Register and watch