Бран · продюсер MMORPG «Хроники Пограничья»
Прошлый подрядчик оставил отчёт по каналам привлечения. По нему органика приносит 434 тысячи, а реклама копейки. Я уже собрался резать рекламный бюджет. Посмотрите запрос, ему можно верить?
Вот что оставил подрядчик, слово в слово:
select a.channel,count(distinct a.id) players,count(distinct b.player_id) payers,sum(b.amount_rub) revenue
from players a left join purchases b on a.id=b.player_id left join characters c on a.id=c.player_id
where b.status='paid' or b.status is null and a.email not like '%@studio.dev'
group by 1 order by 4 desc
channel | players | payers | revenue
------------+---------+--------+-----------
organic | 1563 | 219 | 434134.00
ads_vk | 804 | 102 | 152527.00
crosspromo | 418 | 62 | 147893.00
ads_yandex | 587 | 68 | 56127.00
bloggers | 712 | 55 | 53076.00
Запрос выполняется, цифры правдоподобные. В сумме 843 757 ₽. А из проекта про экономику Пограничья мы знаем чистую выручку игры: 657 756 ₽. Откуда-то взялись лишние 186 тысяч, и в четырёх строках не видно откуда. Сегодня учимся писать так, чтобы такие ошибки было видно, и читать чужие запросы так, чтобы их находить.
Столбик цифр в тетради
В школе учитель просил писать сложение столбиком: единицы под единицами, десятки под десятками. Не для красоты. Когда цифры стоят ровно, ошибку в переносе видно глазами. Сложи те же числа в строчку, и ошибку придётся искать пересчётом.
Стайлгайд SQL работает так же. Каждое условие на своей строке, каждый столбец на своей строке, каждый шаг расчёта под своим именем. Тогда «OR посреди столбика AND» и «DISTINCT там, где строк должно быть по одной» бросаются в глаза.
Стайлгайд «Северного Тракта»
Агентство договорилось о десяти правилах. Первые шесть про то, как запрос выглядит, последние четыре про ловушки, которые оформление помогает поймать.
- Ключевые слова заглавными, имена строчными.
SELECT,FROM,LEFT JOIN, а функции и столбцы как в курсе:count(*),amount_rub. - Один столбец на строку, части запроса с новой строки:
SELECT,FROM, каждыйJOIN,WHERE,GROUP BY. УсловияWHEREиONтоже по одному на строку,ANDв начале строки. - Осмысленные псевдонимы.
plдляplayers,revдля выручки на игрока. Неa,b,cпо порядку появления: на десятой строке уже не вспомнить, что такоеb. - Явный
JOIN ... ON, никогда таблицы через запятую с условиями вWHERE. Условие соединения стоит рядом с таблицей, и его не перепутать с фильтром. GROUP BYиORDER BYпо именам, а не по номерам.GROUP BY 1ломается молча, когда кто-то переставит столбцы.- CTE с говорящими именами вместо матрёшки подзапросов, как в уроке про CTE. Комментарий объясняет «зачем», а не «что»:
-- эхо вебхука: тот же чек второй строкой, а не-- фильтр по id. ORвнутриWHEREвсегда в скобках.ANDсвязывает сильнееOR, и без скобок условие читается не так, как задумано. Для одного столбца лучшеIN (…).- Не
NOT INс подзапросом, аNOT EXISTS. ОдинNULLв подзапросе превращает ответ в пустоту, это мина из урока про подзапросы. - Фильтр по правой таблице
LEFT JOINставим вON, а не вWHERE. Иначе строки без пары молча выпадают, как в уроке про LEFT JOIN. COUNT(DISTINCT …)это запах. Сам по себе он не ошибка, но спроси, почему строки повторяются. Если причина в соединении двух «многих» сторон, тоsumв том же запросе посчитан по размноженным строкам.
урок из курса
Урок из курса «Аналитика данных с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.