Недавно как раз экспериментировал. Сразу оговорюсь - не моё.
Если поискать, можно найти еще несколько разных вариантов.
ЗапросСКЛ.УложитьСписокОбъектов(сз,ВремТаб,"Товары");
КолДней = (КонДата-НачДата);
ТекстЗапроса = "
|Set NoCount On
|
|Declare @НачДата DATETIME, @КонДата DATETIME
|Set @НачДата = '"+Формат(НачДата,"ДДДММГГ")+"'
|Set @КонДата = '"+Формат(КонДата,"ДДДММГГ")+"'
|
|Select
| Период,
| Товар,
| ОстатокТовараНачальныйОстаток as НачОст,
| ОстатокТовараПриход as Приход,
| ОстатокТовараРасход as Расход,
| ОстатокТовараКонечныйОстаток as КонОст
|Into "+ВремТабОстОб+"
|From $РегистрОстаткиОбороты.ТоварыОстатки(:НачДата,:КонДата~,День,,,(Товар IN (SELECT val FROM "+ВремТаб+")),(Товар),(ОстатокТовара))
|
|--в остаткахОборотах, даже Если использовать метод дополнения ""ДвиженияИГраницыПериода"", может не быть остатка на начало периода.
|Insert Into "+ВремТабОстОб+"
|Select
| @НачДата as Период,
| ост.Товар,
| ост.ОстатокТовараОстаток as НачОст,
| 0 as Приход,
| 0 as Расход,
| ост.ОстатокТовараОстаток as КонОст
|From $РегистрОстатки.ТоварыОстатки(:НачДата,,(Товар IN (SELECT val FROM "+ВремТаб+")),(Товар),(ОстатокТовара)) as ост
|Where Not Exists(Select * From "+ВремТабОстОб+" as об Where ост.Товар = об.Товар and об.Период = @НачДата)
|
|
|Select
| кросс.день,
| кросс.Товар,
| Ост.КонОст
|Into "+ВремТабИтог+"
|From (
| Select дни.день,val as Товар
| From (
| Select DATEADD(day,(aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d),@НачДата) as день
| From (Select 0 AS a UNION Select 1 UNION Select 2 UNION Select 3 UNION Select 4 UNION Select 5 UNION Select 6 UNION Select 7 UNION Select 8 UNION Select 9) AS aa
| CROSS JOIN (Select 0 AS b UNION Select 1 UNION Select 2 UNION Select 3 UNION Select 4 UNION Select 5 UNION Select 6 UNION Select 7 UNION Select 8 UNION Select 9) AS bb
| CROSS JOIN (Select 0 AS c UNION Select 1 UNION Select 2 UNION Select 3 UNION Select 4 UNION Select 5 UNION Select 6 UNION Select 7 UNION Select 8 UNION Select 9) AS cc
| CROSS JOIN (Select 0 AS d UNION Select 1 UNION Select 2 UNION Select 3 UNION Select 4 UNION Select 5 UNION Select 6 UNION Select 7 UNION Select 8 UNION Select 9) AS dd
| Where aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d <= "+КолДней+"
| ) as дни
| CROSS JOIN "+ВремТаб+"
| ) as кросс
|
| LEFT JOIN (
| Select
| об1.Период as ДатаС,
| MIN(CASE WHEN об2.Период Is NULL THEN DATEADD(day,1,@КонДата) ELSE DATEADD(day,-1,об2.Период) END) as ДатаПо,
| об1.КонОст,
| об1.Товар
| From "+ВремТабОстОб+" об1
| LEFT JOIN "+ВремТабОстОб+" об2 on об1.Товар = об2.Товар and об1.Период < об2.Период
| Group By об1.Период,об1.Товар,об1.КонОст
| ) as Ост on кросс.Товар = Ост.Товар and кросс.день BETWEEN Ост.ДатаС AND Ост.ДатаПо
|Where Ост.КонОст <> 0 --Если нужны дни без остатков, то это строку закомментарить
|ORDER BY кросс.Товар,кросс.день
|";
ЗапросСКЛ.УстановитьТекстовыйПараметр("НачДата",НачДата);
ЗапросСКЛ.УстановитьТекстовыйПараметр("КонДата",КонДата);
ЗапросСКЛ.Выполнить(ТекстЗапроса);
Кстати, заодно может просветит кто, почему в РегистрОстаткиОбороты даже если использовать метод дополнения "ДвиженияИГраницыПериода", может не быть остатка на начало периода (остаток стопудово не нулевой)? 1сpp 3.2.1.14
Еще как вариант (здесь считается количество дней с ненулевым остатоком):
ТекстЗапроса = "
|SELECT
| ВлЗапрос.Фирма [Фирма $Справочник.Фирмы]
| ,ВлЗапрос.Номенклатура [ПодзапросНоменклатура $Справочник.Номенклатура]
| ,SUM(
| CASE WHEN ВлЗапрос.НачОст>0 THEN
| CASE WHEN ВлЗапрос.Период=convert(datetime,:НачДата,112) THEN
| CASE WHEN ВлЗапрос.КонОст<=0 THEN
| 1
| ELSE
| DATEDIFF(day, ВлЗапрос.Период,convert(datetime,:КонДата,112)) + 1
| END
| ELSE
| CASE WHEN ВлЗапрос.КонОст<=0 THEN
| -DATEDIFF(day, ВлЗапрос.Период,convert(datetime,:КонДата,112))
| END
| END
| ELSE
| CASE WHEN ВлЗапрос.КонОст>0 THEN
| DATEDIFF(day, ВлЗапрос.Период,convert(datetime,:КонДата,112)) + 1
| END
| END) as ДнейНаСкладе
|FROM(
| SELECT ОстаткиТМЦОстаткиОбороты.Фирма
| , ОстаткиТМЦОстаткиОбороты.Номенклатура
| , ОстаткиТМЦОстаткиОбороты.Период as Период
| , ОстаткиТМЦОстаткиОбороты.КоличествоКонечныйОстаток КонОст
| , ОстаткиТМЦОстаткиОбороты.КоличествоНачальныйОстаток НачОст
| FROM риода,
| ,
| Номенклатура in (select val from #СписокТоваров)
| ,(Номенклатура, Фирма),) AS ОстаткиТМЦОстаткиОбороты
| ) AS ВлЗапрос
| GROUP BY ВлЗапрос.Фирма
| , ВлЗапрос.Номенклатура
| ORDER BY ВлЗапрос.Номенклатура
|";