После объединения отчёта по расходам с таблицей лидов итог может вырасти в два раза, хотя исходные файлы не менялись. Причина обычно в разной детализации строк: расход записан один раз на дату и кампанию, а лиды разбиты ещё и по устройствам. Один расход повторяется для каждого совпавшего устройства.
Перед объединением запишите, что означает одна строка в каждой таблице, проверьте уникальность ключа и сравните контрольную сумму расходов до и после операции. Если обе стороны содержат несколько строк с одинаковым ключом, сначала приведите их к общей детализации.
Запишите детализацию каждой таблицы
Рабочее правило помещается в одну строку:
Одна строка таблицы расходов \= дата × кампания; одна строка таблицы лидов \= дата × кампания × устройство.
Для таблицы расходов ключом будет пара date + campaign. В таблице лидов эта пара повторяется, потому что к ней добавлено устройство. Объединение только по дате и кампании создаёт несколько совпадений для одной строки расхода.
В документации PostgreSQL сказано, что при INNER JOIN для каждой строки первой таблицы результат содержит строку для каждой подходящей строки второй таблицы. Поэтому два совпадения справа дают две строки в результате. Это обычное поведение join, а не ошибка базы данных.
Учебный пример: 260 BYN превращаются в 520 BYN
В выгрузке расходов три строки:
| Дата | Кампания | Расход, BYN |
|---|---|---|
| 1 октября | search_brand | 120,00 |
| 2 октября | search_brand | 80,00 |
| 1 октября | remarketing | 60,00 |
| Итого | 260,00 |
Вторая таблица хранит лиды по устройствам:
| Дата | Кампания | Устройство | Лиды |
|---|---|---|---|
| 1 октября | search_brand | mobile | 3 |
| 1 октября | search_brand | desktop | 2 |
| 2 октября | search_brand | mobile | 4 |
| 2 октября | search_brand | desktop | 1 |
| 1 октября | remarketing | mobile | 1 |
| 1 октября | remarketing | desktop | 1 |
После объединения по date + campaign каждая строка расходов встречает две строки лидов. Значения 120, 80 и 60 BYN повторяются по два раза. Сумма становится 520 BYN, число лидов остаётся 12, а CPL меняется с 21,67 до 43,33 BYN.
Удвоение возникает в момент соединения таблиц разной детализации. Контрольная сумма показывает ошибку до расчёта CPL.
Найдите размножение строк до расчёта показателей
1. Проверьте уникальность ожидаемого ключа
В таблице расходов комбинация date + campaign должна встречаться один раз, если расход уже собран на этом уровне. Повторы означают, что в ключе не хватает поля либо таблица содержит дубли.
В таблице лидов такой же ключ повторяется ожидаемо: строки разделены по устройствам. Для соединения один к одному эту таблицу нужно предварительно агрегировать.
2. Посчитайте совпадения по каждому ключу
Соберите служебный отчёт:
| Ключ | Строк расходов | Строк лидов | Риск |
|---|---|---|---|
1 октября + search_brand | 1 | 2 | расход повторится дважды |
2 октября + search_brand | 1 | 2 | расход повторится дважды |
1 октября + remarketing | 1 | 2 | расход повторится дважды |
Если по одному ключу несколько строк есть с обеих сторон, получится связь многие ко многим. Для рекламного отчёта это повод остановить расчёт и выяснить недостающие измерения.
3. Сверьте аддитивные показатели
До объединения сохраните число строк и суммы расходов, кликов, показов, лидов и выручки. После операции сравните их с исходниками. Допустимое изменение нужно объяснить заранее; необъяснённый рост расходов блокирует приёмку.
CTR, CPC, CPL и конверсию пересчитывайте после сверки сумм. Простая сумма или среднее значений этих столбцов даёт неверный результат при разном весе строк.
4. Проверьте строки без пары
Отдельно сохраните ключи, которые есть только в одной таблице. Расход без строки лидов может быть допустимым нулевым результатом кампании. Лиды без кампании расходов могут указывать на разные названия, часовые пояса, правила атрибуции или неполный период.
Приведите таблицы к общей детализации
Для расчёта CPL по дате и кампании сначала сложите лиды по устройствам:
| Дата | Кампания | Расход, BYN | Лиды | CPL, BYN |
|---|---|---|---|---|
| 1 октября | search_brand | 120,00 | 5 | 24,00 |
| 2 октября | search_brand | 80,00 | 5 | 16,00 |
| 1 октября | remarketing | 60,00 | 2 | 30,00 |
| Итого | 260,00 | 12 | 21,67 |
Теперь обе таблицы имеют одну строку на date + campaign, и расход входит в итог один раз. Если нужен CPL по устройствам, потребуется отдельное правило распределения расходов или источник, где расходы уже доступны по устройствам. Копирование всей суммы в каждую строку устройства не создаёт такого разреза.
Определение CPL и проверку квалификации лида можно сверить с ответом «Что такое CPL и как рассчитать стоимость лида». Для сравнения периодов используйте одинаковое определение лида и один состав расходов.
Запустите воспроизводимую проверку
В комплекте сохранены две исходные таблицы и скрипт на стандартной библиотеке Python:
python3 check_join_grain.py \
ad-spend.csv leads-by-device.csv \
join-audit-report.csv naive-joined.csv correct-joined.csvРезультат учебного примера:
spend_before=260.00 spend_after_naive=520.00 multiplier=2.00 correct_cpl=21.67 naive_cpl=43.33Комплект добавлен 21 октября 2026 года. Обе таблицы и результаты 260/520 BYN — синтетический пример из статьи, не клиентские показатели. В архиве — полный скрипт, входные CSV, README и три отчёта, созданные опубликованной командой. Скачать комплект.
Скрипт останавливается, если ключ расходов повторяется, сохраняет ошибочное и исправленное объединение и формирует контрольный отчёт. Для рабочего файла добавьте поля, которые входят в вашу единицу строки: аккаунт, валюта, источник, идентификатор кампании и часовой пояс.
В pandas ту же проверку можно зафиксировать параметром validate функции merge: режим one_to_one требует уникальных ключей с обеих сторон, one_to_many — только слева. Режим many_to_many разрешает повторяющиеся ключи и не выполняет такую проверку. Тип связи выбирают по фактической структуре данных.
Что сохранить вместе с отчётом
Минимальный комплект приёмки содержит:
- исходные файлы без ручных исправлений;
- описание одной строки и ключ каждой таблицы;
- число строк и контрольные суммы до объединения;
- список повторяющихся и отсутствующих ключей;
- запрос, формулу или скрипт преобразования;
- суммы после объединения и объяснение допустимых изменений.
Если названия кампаний различаются по регистру или пробелам, сначала примените правила из статьи о нормализации UTM-меток. Затем повторите проверку ключей и сумм. Для сводки, подготовленной ИИ, используйте дополнительный протокол сверки строк рекламного отчёта.
Критерий готовности
Объединённый отчёт готов к расчёту показателей, когда единица строки записана для каждого источника, ожидаемые ключи уникальны, строки без пары вынесены отдельно, а суммы расходов и лидов совпадают с исходниками. После этого CPL рассчитывается из итоговых расходов и итоговых лидов на согласованном уровне детализации.
Ограничения проверки
Контроль ключей обнаруживает размножение и потерю строк, но не подтверждает правильность атрибуции. Даже технически корректное объединение может сопоставить расход и лиды по разным временным зонам, моделям атрибуции или определениям кампании. Эти правила фиксируют отдельно до интерпретации результата.
Источники
Материал подготовлен редакцией WiseLab с помощью AI. Источники и фактические утверждения проверены при подготовке.
Что думаете?
Загружаем комментарии…