Как сгенерировать последовательность чисел в SQL
Что проверяют
Знаете ли вы способы под свою СУБД и понимаете ли, зачем это нужно в аналитике. Следом часто просят применить: построить календарь и показать дни без продаж нулями.
Как отвечать
Способ зависит от диалекта, поэтому назовите несколько:
- PostgreSQL:
generate_series(1, 10), с шагомgenerate_series(0, 100, 5)и для датgenerate_series(date '2026-01-01', date '2026-01-31', interval '1 day'). Обе границы включаются; - рекурсивный CTE:
WITH RECURSIVEс начальной строкой и шагомn + 1до условия остановки. Работает в PostgreSQL, MySQL 8, SQLite. В SQL Server словоRECURSIVEне пишется, а глубина по умолчанию ограничена 100 уровнями и снимается черезOPTION (MAXRECURSION 0). В MySQL предел задаётcte_max_recursion_depth, по умолчанию 1000; - SQL Server 2022: появилась своя
GENERATE_SERIES(start, stop, step); - ClickHouse: табличная функция
numbers(10)отдаёт числа от 0 до 9,numbers(5, 10)десять чисел начиная с 5; - BigQuery и Spark: массив
GENERATE_ARRAY(1, 10)илиsequence(1, 10)разворачивают черезUNNESTилиexplode, в Spark есть ещёrange(1, 11); - таблица чисел: заранее созданная таблица или
CROSS JOINнабора цифр 0..9 самого с собой, если функций нет.
Главный практический сценарий: сгенерировать сплошной ряд дат и сделать к нему LEFT JOIN с фактами, чтобы во временном ряде не было дыр. Без этого скользящее среднее и лаги для модели считаются по пропущенным дням неверно.
По скорости: generate_series и numbers отдают миллионы строк быстро, рекурсивный CTE строит их по одной и на больших объёмах заметно медленнее.
Где спотыкаются
Путают границы. generate_series включает верхнюю, range в Spark её исключает, numbers(10) в ClickHouse начинается с нуля. Отсюда ошибки на единицу в календарях.
Пишут рекурсию без условия остановки или упираются в лимит глубины и не знают, где он настраивается.
Нумеруют строки случайной таблицы через ROW_NUMBER(). Результат зависит от числа строк в ней и ломается, когда таблица меньше нужного диапазона.