SQL-запрос по описанию
В бенчмарке моделей эту задачу сейчас лучше всех решают: 1. Claude Opus 4.8 — 10,0 · 2. Claude Sonnet 5 — 10,0 · 3. GLM 5.3 — 9,5
Ты — аналитик данных, который пишет запросы для продуктовых менеджеров. Напиши SQL-запрос по вопросу на естественном языке и схеме таблиц.
Входные данные: — схема таблиц: [вставьте таблицы, их колонки и связи между ними]; — вопрос: [вставьте вопрос на естественном языке — что нужно узнать данными]; — диалект: [вставьте СУБД или диалект: PostgreSQL, ClickHouse, BigQuery и т. п.].
Сделай следующее:
- Перескажи своими словами, на какой вопрос отвечает запрос. Затем перечисли допущения — как ты понял неоднозначные места вопроса и схемы: определения периода, «активного пользователя», уникальности, границы дат. Каждое допущение — отдельным пунктом.
- Напиши один SQL-запрос, отвечающий на вопрос. Оформи код в блоке с подсветкой sql и прокомментируй каждый смысловой блок: что делает CTE, фильтр, соединение и агрегация.
- Если ответить одним запросом нельзя или в схеме не хватает колонки или таблицы — скажи прямо: назови, чего именно не хватает, и предложи ближайший запрос, который можно выполнить уже сейчас.
- Перечисли, что проверить перед запуском на проде: объём данных и период, корректность соединений, потери строк из-за дубликатов, значения статусов, права доступа, часовой пояс.
Ограничения: — используй только таблицы и колонки из схемы: не выдумывай их названия; — если диалект не указан, пиши на стандартном SQL и явно отметь это; — не подставляй свои значения периодов и статусов — бери их из вопроса и схемы; — если данных не хватает, отметь это и напиши, что уточнить у тех, кто владеет схемой.
Пример данных
Данные вымышлены. Замени их информацией о своей задаче.
Диалект: PostgreSQL. Схема таблиц: searches (id, user_id, created_at, destination_city, source) — по строке на поиск перелётов; search_offers (id, search_id, provider, price, currency) — варианты от провайдеров по поиску; bookings (id, search_id, user_id, created_at, status, gross_booking_value) — статус: completed, cancelled, pending. Вопрос: какая доля поисков за последний полный месяц заканчивается бронированием со статусом completed и как средний чек такой брони различается по источнику поиска (source)?
Пример ответа
Один из возможных результатов. Проверь факты и адаптируй текст перед использованием.
На какой вопрос отвечает запрос
Доля поисков, у которых есть хотя бы одна бронь со статусом completed, по источникам поиска за предыдущий полный календарный месяц — и средний чек завершённых броней по этим же источникам.
Допущения
- «Последний полный месяц» — предыдущий календарный месяц целиком. Запрос привязан к дате запуска: при запуске в августе он считает июль. Если отчётный месяц фиксирован, период лучше задать датами явно.
- Поиск считается конвертированным, если у него есть хотя бы одна бронь completed. Несколько завершённых броней у одного поиска — это один конвертированный поиск.
- Средний чек считается только по брони со статусом completed; cancelled и pending не участвуют.
- Средний чек считается по всем завершённым броням периода без группировки: AVG(gross_booking_value) на уровне брони. Осреднение средних по поискам исказило бы метрику — поиск с одной бронью и поиск с пятью получили бы одинаковый вес.
- Поиск мог произойти в июне, а бронь по нему — в июле: брони привязаны к периоду по дате создания брони, поэтому отчёт за закрытый месяц может меняться задним числом. Если это недопустимо, нужен явный промежуток между поиском и бронью — во входных данных его нет, это допущение.
- В таблице bookings нет колонки валюты: если gross_booking_value приходит в разных валютах, средний чек по источнику будет некорректен. Запрос ниже считает, что значения сравнимы.
SQL
-- 1. Поиски за предыдущий полный календарный месяц
WITH month_searches AS (
SELECT
s.id,
s.source
FROM searches AS s
WHERE s.created_at >= date_trunc('month', current_date) - interval '1 month'
AND s.created_at < date_trunc('month', current_date)
),
-- 2. Завершённые брони того же месяца: средний чек считается
-- на уровне брони, а не средним по поискам
month_bookings AS (
SELECT
b.search_id,
b.gross_booking_value
FROM bookings AS b
WHERE b.status = 'completed' -- отменённые и ожидающие не учитываем
AND b.created_at >= date_trunc('month', current_date) - interval '1 month'
AND b.created_at < date_trunc('month', current_date)
)
-- 3. Конверсия поиска в бронь и средний чек брони по источникам
SELECT
ms.source,
COUNT(*) AS searches,
COUNT(DISTINCT mb.search_id) AS searches_with_completed,
ROUND(100.0 * COUNT(DISTINCT mb.search_id)
/ NULLIF(COUNT(*), 0), 2) AS conversion_pct,
ROUND(AVG(mb.gross_booking_value), 2) AS avg_completed_value
FROM month_searches AS ms
LEFT JOIN month_bookings AS mb
ON mb.search_id = ms.id
GROUP BY ms.source
ORDER BY searches DESC;
Одним запросом ответить можно: LEFT JOIN оставляет поиски без завершённых броней, и они попадают в знаменатель доли.
Что проверить перед запуском на проде
- Период и таймзона:
date_truncпривязан к текущей дате сервера; убедиться, чтоcreated_atхранится в ожидаемой таймзоне, иначе граница месяца сдвинется. - Дубликаты броней: если одна бронь меняет статус и остаётся несколькими строками,
completed_cntзавышен; проверить уникальностьbookings.id. - Значения статусов: расчёт опирается на перечень completed, cancelled, pending из схемы; если в данных есть статусы вне перечня (например возврат), уточнить, чем их считать.
- Объём данных: сначала оценить количество поисков за месяц; на больших объёмах добавить индекс по
created_atили считать по партициям. - Права доступа: bookings содержит платёжные суммы — доступ на чтение может быть ограничен.
- Валюта: сверить, в одной ли валюте
gross_booking_value(см. последнее допущение).
Проверьте факты
- Состав статусов bookings (completed, cancelled, pending) взят из схемы: подтвердить, что в данных нет других значений.
- Привязка «последний полный месяц» к дате запуска — допущение: у владельца вопроса уточнить фиксированный период.
- Колонки bookings.currency в схеме нет — сравнимость сумм по валюте не проверена.
- Правило «один поиск — один конвертированный поиск» при нескольких бронях — допущение: сверить с аналитиком.
Из главы: Аналитика и метрики