поскольку, всё же, очень хочется вникнуть хотя бы до момента когда в голове уже не будет каша из неясностей и предположений, и понятна будет область возможностей, то... малость разогрел мосх и из предыдущего запроса по регистру остатки сваял вот это:
|SELECT
| Т.Номенклатура [Номенклатура :Справочник.Номенклатура]
| ,Т.Фирма [Фирма :Справочник.Фирмы]
| ,Т.Склад [Склад :Справочник.Склады]
| ,Т.НачОст [НачОст :Число.15.5]
| ,Т.Приход [Приход :Число.15.5]
| ,Т.Расход [Расход :Число.15.5]
| ,Т.КонОст [КонОст :Число.15.5]
| ,Т.Документ [Документ :Документ]
|FROM (
|
|
|SELECT
| Рег.Номенклатура Номенклатура
| ,Рег.Фирма Фирма
| ,Рег.Склад Склад
| ,CASE Рег.Документ
| WHEN ' ПодИтог' THEN
| Рег.НачОст
| ELSE
| SUM(Рег.НачОст) OVER(PARTITION BY Рег.Склад, Рег.Номенклатура ORDER BY Рег.Документ ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
| END AS НачОст
| ,CASE Рег.Документ
| WHEN ' ПодИтог' THEN
| SUM(Рег.Приход) OVER(PARTITION BY Рег.Склад, Рег.Номенклатура)
| ELSE
| Рег.Приход
| END AS Приход
| ,CASE Рег.Документ
| WHEN ' ПодИтог' THEN
| SUM(Рег.Расход) OVER(PARTITION BY Рег.Склад, Рег.Номенклатура)
| ELSE
| Рег.Расход
| END AS Расход
| ,CASE Рег.Документ
| WHEN ' ПодИтог' THEN
| SUM(Рег.НачОст) OVER(PARTITION BY Рег.Склад, Рег.Номенклатура)
| ELSE
| SUM(Рег.НачОст) OVER(PARTITION BY Рег.Склад, Рег.Номенклатура ORDER BY Рег.Документ ROWS UNBOUNDED PRECEDING)
| END AS КонОст
| ,Рег.Документ
|FROM
| (
| SELECT
| Итоги.Номенклатура Номенклатура
| ,Итоги.Фирма Фирма
| ,Итоги.Склад Склад
| ,Итоги.Количество НачОст
| ,0 Приход
| ,0 Расход
| ,' ПодИтог' Документ
| FROM
| [РегистрИтоги.ОстаткиТМЦ] AS Итоги
|
| WHERE
| Итоги.PERIOD = :ПредПериод
| UNION ALL
| SELECT
| Движения.Номенклатура
| ,Движения.Фирма
| ,Движения.Склад
| ,Движения.Количество * (1 - Движения.DEBKRED * 2)
| ,0
| ,0
| ,' ПодИтог'
| FROM
| [Регистр.ОстаткиТМЦ] AS Движения
| -- это расскоментить, если нет галки
| INNER JOIN [Журнал] Жур ON Жур.IDDOC = Движения.IDDOC AND Жур.DATE BETWEEN :НачПериод AND :КонПериод
| --WHERE --это если есть галка быстрая обработка движений
| -- Движения.DATE BETWEEN :НачПериод AND :КонПериод
| UNION ALL
| SELECT
| Движения2.Номенклатура
| ,Движения2.Фирма
| ,Движения2.Склад
| ,Движения2.Количество * (1 - Движения2.DEBKRED * 2)
| ,Движения2.Количество *( 1-Движения2.DEBKRED)
| ,Движения2.Количество * Движения2.DEBKRED
| ,Жур2.IDDOCDEF||Движения2.IDDOC
| FROM
| [Регистр.ОстаткиТМЦ] Движения2
| INNER JOIN [Журнал] Жур2 ON Жур2.IDDOC = Движения2.IDDOC AND Жур2.DATE BETWEEN :Дата1 AND :Дата2
| --WHERE --это если есть галка быстрая обработка движений
| -- Движения2.DATE BETWEEN :Дата1 AND :Дата2
|) Рег
|
|
|) Т
|WHERE NOT (Т.Расход = 0) OR NOT (Т.Приход = 0)
|GROUP BY Т.Номенклатура, Т.Фирма, Т.Склад, Т.Документ
Я понимаю, что несколько не оптимально накладывать условия приход/расход и перегруппировывать во внешнем запросе, но это просто экспериментально и, что удивительно, практически не влияет на время выполнения даже для больших выборок. Ну и сомнительна идея с добавлением сущности
ПодИтог, но это тоже просто проба.
Работает очень быстро раз в 20-70 быстрее чОрных запросов.
Сразу вопрос: как типизировать
Т.Документ, чтобы были и ссылки на документы, и осталась строка
' ПодИтог'?
добавлено: увидел, что в оконных группировках не хватает Фирмы.
добавлено: также понял, что повторяющиеся окна можно описать через
WINDOW. Никак не могу найти понятный и более менее полный учебник/доку по SQL без упора на MSSQL. Дока на sqlite.org очень удобна, но очень лаконична, что весьма ограничивает её для меня.