Преобразуйте заезды в +1, выезды в −1, посчитайте дневные изменения и накопительную сумму по календарю. Это верно для полного, очищенного лога с корректными переходами состояний.
Дан лог заездов/выездов в гостиницу. Лог состоит из записей (ts, user_id, event_type).
Преобразуйте заезды в +1, выезды в −1, посчитайте дневные изменения и накопительную сумму по календарю. Это верно для полного, очищенного лога с корректными переходами состояний.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Дан лог заездов/выездов в гостиницу. Лог состоит из записей (ts, user_id, event_type). Надо найти сколько было постояльцев на каждый день существования гостиницы. Число постояльцев считается на конец дня.
Ответ
Преобразуйте заезды в +1, выезды в −1, посчитайте дневные изменения и накопительную сумму по календарю. Это верно для полного, очищенного лога с корректными переходами состояний.
Предположим, что check_in/check_out — значения event_type, на открытии гостиницы гостей нет, а calendar(day) содержит каждый день нужного периода:
WITH daily AS (
SELECT CAST(ts AS date) AS day,
SUM(CASE event_type WHEN 'check_in' THEN 1
WHEN 'check_out' THEN -1 ELSE 0 END) AS delta
FROM hotel_log
GROUP BY CAST(ts AS date)
)
SELECT c.day,
SUM(COALESCE(d.delta, 0)) OVER (
ORDER BY c.day ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS guests
FROM calendar c LEFT JOIN daily d ON d.day = c.day
ORDER BY c.day;
День определяют в часовом поясе гостиницы. Дубли событий удаляют, а по user_id проверяют чередование заезда/выезда: два заезда подряд нельзя считать двумя гостями. Для лога не с момента открытия добавьте начальный остаток. День без событий обязан остаться в результате.