Короткий ответ
Данные из каждого источника нужно привести к одинаковой структуре столбцов (дата, канал, расход, конверсии) отдельными запросами, а затем объединить через UNION ALL в одну таблицу для дальнейшей агрегации.
Как это работает подробнее
Поскольку таблицы из разных источников обычно имеют разные названия столбцов (например, cost в одной, spend в другой), сначала их приводят к единым алиасам, а затем объединяют запросом с UNION ALL, после чего группируют по дате и каналу. При появлении новых источников (например, TikTok Ads) структуру запроса удобно расширять добавлением ещё одного блока UNION ALL с тем же набором алиасов столбцов, без изменения логики агрегации.
Пример кода
daily_cross_channel_report.sql
WITH unified AS (
SELECT report_date, 'google-ads' AS channel, cost AS spend, conversions FROM google_ads
UNION ALL
SELECT report_date, 'meta-ads' AS channel, spend, conversions FROM meta_ads
)
SELECT report_date, channel, SUM(spend) AS spend, SUM(conversions) AS conversions
FROM unified
GROUP BY report_date, channel
ORDER BY report_date, channel;Что использовать на практике
- Практика. На практике такую объединённую таблицу удобно материализовать (сохранить как отдельную таблицу или view) и обновлять по расписанию, а не пересчитывать на лету при каждом открытии дашборда, особенно если источников много. Полезно также вынести приведение названий каналов к единому стандарту (например, все в нижнем регистре) в отдельный шаг трансформации, чтобы не дублировать эту логику в каждом запросе.
- Пример. Сведите нормализованные строки рекламных источников без удаления допустимых повторов; контрольная сумма расхода Google в результате должна совпадать с исходными данными за тот же период.
Подводные камни
- Риск. Частая ошибка — использовать UNION вместо
UNION ALLтам, где по логике дублей быть не может, что приводит к незаметной потере строк при случайном совпадении значений, или забывать привести форматы дат к одному стандарту перед объединением.