Запрос получить таблицу дат

Хотите быстро получить таблицу дат через запрос? Покажем рабочие примеры для SQL Server, MySQL и PostgreSQL — копируйте и используйте прямо сейчас!

Бесплатная консультация юриста

+7 (800) 302-87-29

Реклама jurik.ru

Одна из частых задач при разработке отчётов и обработок в 1С — получить в запросе таблицу дат за определённый период. Например‚ это нужно для построения отчётов по дням‚ когда в некоторые дни нет данных‚ но строки в отчёте должны присутствовать. В этой статье разберём основные способы решения задачи.

Зачем нужна таблица дат

Таблица дат (календарь) полезна в следующих ситуациях:

  • формирование отчётов‚ где нужно показать все дни периода‚ включая дни без оборотов;
  • расчёт скользящих средних и накопительных итогов;
  • план-фактный анализ по дням‚ неделям‚ месяцам;
  • заполнение графиков и диаграмм с непрерывной осью времени.

Способ 1. Генерация дат через декартово произведение таблицы чисел

Классический приём — создать в запросе вспомогательную таблицу чисел от 0 до 9‚ а затем соединить её саму с собой несколько раз. Так можно получить последовательность чисел‚ которую затем преобразовать в даты функцией ДОБАВИТЬКДАТЕ.

ВЫБРАТЬ 0 КАК Цифра
ПОМЕСТИТЬ ВТ_Цифры
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 9
;
////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ДОБАВИТЬКДАТЕ(&НачалоПериода‚ ДЕНЬ‚
		ВТ_Цифры2.Цифра * 100 + ВТ_Цифры1.Цифра * 10 + ВТ_Цифры.Цифра) КАК Дата
ИЗ
	ВТ_Цифры КАК ВТ_Цифры‚
	ВТ_Цифры КАК ВТ_Цифры1‚
	ВТ_Цифры КАК ВТ_Цифры2
ГДЕ
	ДОБАВИТЬКДАТЕ(&НачалоПериода‚ ДЕНЬ‚
		ВТ_Цифры2.Цифра * 100 + ВТ_Цифры1.Цифра * 10 + ВТ_Цифры.Цифра)
		МЕЖДУ &НачалоПериода И &КонецПериода
УПОРЯДОЧИТЬ ПО
	Дата

Три соединения таблицы цифр дают 1000 комбинаций, этого достаточно для периода почти в три года. Если нужен больший диапазон‚ добавьте ещё одно соединение.

Способ 2. Использование регистра сведений «Регламентированный производственный календарь»

В типовых конфигурациях (БП‚ ЗУП‚ ERP) есть регистр сведений с календарём. Получить даты можно простым запросом:

ВЫБРАТЬ
	Календарь.ДатаКалендаря КАК Дата
ИЗ
	РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК Календарь
ГДЕ
	Календарь.ДатаКалендаря МЕЖДУ &НачалоПериода И &КонецПериода
УПОРЯДОЧИТЬ ПО
	Дата

Это самый быстрый и надёжный способ‚ но он работает только если регистр заполнен на нужный период.

Способ 3. Программное формирование таблицы значений

Если логика сложная (например‚ настраиваемый шаг в днях)‚ удобнее сформировать таблицу значений встроенным языком и передать её в запрос как временную таблицу:

Функция ПолучитьТаблицуДатЗаПериод(НачДата‚ КонДата‚ ШагДней = 1)

	тзИнтервалов = Новый ТаблицаЗначений;
	тзИнтервалов.Колонки.Добавить("НачИнтервала"‚ Новый ОписаниеТипов("Дата"));
	ТекДата = НачалоДня(НачДата);
	Пока ТекДата <= КонДата Цикл
		НоваяСтрока = тзИнтервалов.Добавить;
		НоваяСтрока.НачИнтервала = ТекДата;
		ТекДата = ТекДата + ШагДней * 86400; // шаг в секундах
	КонецЦикла;

	Возврат тзИнтервалов;

КонецФункции

Далее таблица помещается в запрос через менеджер временных таблиц:

Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ
|	ТаблицаДат.НачИнтервала КАК Дата
|ПОМЕСТИТЬ ВТ_Даты
|ИЗ
|	&ТаблицаДат КАК ТаблицаДат";
Запрос.УстановитьПараметр("ТаблицаДат"‚ тзИнтервалов);
Запрос.Выполнить;

Полезные функции языка запросов для работы с датами

  • ДОБАВИТЬКДАТЕ(Дата‚ Период‚ Количество) — прибавляет к дате заданное число периодов (СЕКУНДА‚ МИНУТА‚ ЧАС‚ ДЕНЬ‚ МЕСЯЦ‚ КВАРТАЛ‚ ГОД);
  • РАЗНОСТЬДАТ(Дата1‚ Дата2‚ Период) — возвращает разницу между датами в указанных единицах. Например‚ РАЗНОСТЬДАТ(ДАТАВРЕМЯ(2016‚9‚28)‚ ДАТАВРЕМЯ(2017‚9‚28)‚ КВАРТАЛ) вернёт 4;
  • НАЧАЛОПЕРИОДА(Дата‚ Период) и КОНЕЦПЕРИОДА(Дата‚ Период) — приведение даты к началу или концу периода;
  • ДАТАВРЕМЯ(Год‚ Месяц‚ День‚ …) — конструктор даты‚ позволяющий получить таблицу «из воздуха»‚ без источника данных.

Рекомендации

  1. Для типовых конфигураций предпочтителен запрос к производственному календарю — он быстрее всего.
  2. Для независимых решений используйте генерацию через таблицу цифр, метод не требует данных в базе.
  3. При сложном шаге (например‚ каждые 3 дня или только рабочие дни по особому графику) формируйте таблицу значений программно.
  4. Всегда ограничивайте выборку условием МЕЖДУ &НачалоПериода И &КонецПериода‚ чтобы не генерировать лишние строки.

Таким образом‚ получить таблицу дат в запросе 1С можно несколькими способами‚ и выбор зависит от конфигурации‚ требуемого периода и шага. Освоив эти приёмы‚ вы сможете строить полноценные отчёты по периодам без «дырок» в данных.