Обычный подход к решению этой задачи - рассчитать "остатки на каждый день" и подсчитать дни наличия товара. Предлагается другой подход: найти все интервалы отсутствия товара и вычесть их общую длину из длины периода. Получается следующий запрос:
ВЫБРАТЬ
Движения.Склад,
Движения.Номенклатура,
Движения.Период,
Движения.КоличествоНачальныйОстаток,
Движения.КоличествоКонечныйОстаток
ПОМЕСТИТЬ Движения
ИЗ
РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, Секунда, , ) КАК Движения
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Движения.Склад,
Движения.Номенклатура,
Движения.Период,
Движения.КоличествоНачальныйОстаток,
Движения.КоличествоКонечныйОстаток
ПОМЕСТИТЬ ДополненныеДвижения
ИЗ
Движения КАК Движения
ОБЪЕДИНИТЬ
ВЫБРАТЬ РАЗЛИЧНЫЕ
НачальныеНули.Склад,
НачальныеНули.Номенклатура,
&НачалоПериода,
0,
0
ИЗ
Движения КАК НачальныеНули
ОБЪЕДИНИТЬ
ВЫБРАТЬ РАЗЛИЧНЫЕ
КонечныеНули.Склад,
КонечныеНули.Номенклатура,
&КонецПериода,
0,
0
ИЗ
Движения КАК КонечныеНули
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Точки.Склад,
Точки.Номенклатура,
Точки.Период,
МАКСИМУМ(Точки.КоличествоНачальныйОстаток) КАК КоличествоНачальныйОстаток,
МАКСИМУМ(Точки.КоличествоКонечныйОстаток) КАК КоличествоКонечныйОстаток
ПОМЕСТИТЬ ТочкиВремени
ИЗ
ДополненныеДвижения КАК Точки
СГРУППИРОВАТЬ ПО
Точки.Склад,
Точки.Номенклатура,
Точки.Период
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Точки.Склад,
Точки.Номенклатура,
МАКСИМУМ(Слева.Период) КАК НачалоОтсутствия,
Точки.Период
ПОМЕСТИТЬ Интервалы
ИЗ
ТочкиВремени КАК Точки
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТочкиВремени КАК Слева
ПО Точки.Склад = Слева.Склад
И Точки.Номенклатура = Слева.Номенклатура
И (Точки.КоличествоНачальныйОстаток = 0)
И (Слева.КоличествоКонечныйОстаток = 0)
И Точки.Период > Слева.Период
СГРУППИРОВАТЬ ПО
Точки.Склад,
Точки.Номенклатура,
Точки.Период
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ РАЗЛИЧНЫЕ
Точки.Склад,
Точки.Номенклатура,
&КонецПериода,
&НачалоПериода
ИЗ
Движения КАК Точки
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Интервалы.Склад,
Интервалы.Номенклатура,
СУММА(РАЗНОСТЬДАТ(Интервалы.Период, Интервалы.НачалоОтсутствия, СЕКУНДА)) / 60 / 60 / 24 КАК ДнейНаличия
ИЗ
Интервалы КАК Интервалы
СГРУППИРОВАТЬ ПО
Интервалы.Склад,
Интервалы.Номенклатура
Чтобы обработать "особые случаи" (когда в начале или в конце интервала остаток будет нулевым), потребовалось добавить записи - "заглушки" по краям интервала. Чтобы учесть возможность, когда периодов отсутствия не было, потребовалось добавить записи полного интервала, из которых при группировке вычитаются интервалы отсутствия.
Из-за этих особых случаев запрос получился длинным, но по идее он простой. Большим плюсом этого подхода является то, что он замечает движения в течении дня. Если же ориентироваться только на остатки в начале/конце дня, то на складе типа "гардероб" (завезли и тут же продали) товар будет всегда отсутствовать.
Возможно, при небольшом объеме данных необходимости повышать быстродействие, выделяя более редкие интервалы отсутствия товаров, и не возникнет. Тогда можно просуммировать собственно интервалы наличия, что выливается в гораздо более короткий запрос (сразу для дней, но можно переделать и для секунд):
ВЫБРАТЬ
Движения.Период,
Движения.Склад,
Движения.Номенклатура,
Движения.КоличествоКонечныйОстаток
ПОМЕСТИТЬ Движения
ИЗ
РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, ДЕНЬ, ДвиженияИГраницыПериода, Склад = &Склад) КАК Движения
;
ВЫБРАТЬ
Интервалы.Склад,
Интервалы.Номенклатура,
СУММА(Интервалы.Интервал) КАК ДнейНаличия
ИЗ
(ВЫБРАТЬ
Было.Склад КАК Склад,
Было.Номенклатура КАК Номенклатура,
РАЗНОСТЬДАТ(Было.Период, МИНИМУМ(Стало.Период), ДЕНЬ) КАК Интервал
ИЗ
Движения КАК Было
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Движения КАК Стало
ПО Было.Склад = Стало.Склад
И Было.Номенклатура = Стало.Номенклатура
И (Было.КоличествоКонечныйОстаток > 0)
И Было.Период < Стало.Период
СГРУППИРОВАТЬ ПО
Было.Период,
Было.Склад,
Было.Номенклатура) КАК Интервалы
СГРУППИРОВАТЬ ПО
Интервалы.Склад,
Интервалы.Номенклатура
Автор: ildarovich
Количество дней недели (понедельников/вторников/...) в заданном диапазоне одним запросом
Определение суммарного покрытия перекрывающихся интервалов
Проверка совпадения таблиц путем сравнения полного и внутреннего соединения
Получить дату через указанное количество [дней, месяцев, лет, ...]