Чтобы решить эту проблему, вам нужно создать отдельные производные таблицы со всеми значениями PeriodYearMonth
(сгенерированными с использованием рекурсивного CTE) и отдельными парами Reg
и PartNo
и CROSS JOIN
их друг для друга, чтобы получить все комбинации столбцов. Затем эту объединенную таблицу можно * LEFT JOIN
преобразовать в исходную таблицу, чтобы получить ComponentRemovals
для каждого Reg
, PartNo
и PeriodYearMonth
, и затем их можно суммировать с помощью оконной функции:
WITH CTE AS (
SELECT CONVERT(DATE, CONCAT(REPLACE(MIN(PeriodYearMonth), ' ', '-'), '-01'), 23) AS date,
CONVERT(DATE, CONCAT(REPLACE(MAX(PeriodYearMonth), ' ', '-'), '-01'), 23) AS max_date
FROM vtRelRepComponentsRemovalsByPartNo
UNION ALL
SELECT DATEADD(MONTH, 1, date), max_date
FROM CTE
WHERE date < max_date
)
SELECT FORMAT(CTE.date, 'yyyy MM') AS PeriodYearMonth
, rp.Reg
, rp.PartNo
, COALESCE(v.ComponentRemovals, 0) AS ComponentRemovals
, SUM(COALESCE(v.ComponentRemovals, 0)) OVER (PARTITION BY rp.Reg, rp.PartNo ORDER BY FORMAT(CTE.date, 'yyyy MM')
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS RunningRemovals
FROM CTE
CROSS JOIN (SELECT DISTINCT Reg, PartNo FROM vtRelRepComponentsRemovalsByPartNo) rp
LEFT JOIN vtRelRepComponentsRemovalsByPartNo v
ON v.PeriodYearMonth = FORMAT(CTE.date, 'yyyy MM')
AND v.Reg = rp.Reg
AND v.PartNo = rp.PartNo
ORDER BY rp.Reg, rp.PartNo, CTE.date
Вывод
PeriodYearMonth Reg PartNo ComponentRemovals RunningRemovals
2019 09 G-NHVP 109-0740V01-137 0 0
2019 10 G-NHVP 109-0740V01-137 1 1
2019 11 G-NHVP 109-0740V01-137 1 2
2019 12 G-NHVP 109-0740V01-137 1 3
2020 01 G-NHVP 109-0740V01-137 1 4
2019 09 G-NHVR 11-13354P 2 2
2019 10 G-NHVR 11-13354P 0 2
2019 11 G-NHVR 11-13354P 0 2
2019 12 G-NHVR 11-13354P 0 2
2020 01 G-NHVR 11-13354P 0 2
2019 09 OO-NSF 11-13354P 0 0
2019 10 OO-NSF 11-13354P 1 1
2019 11 OO-NSF 11-13354P 0 1
2019 12 OO-NSF 11-13354P 0 1
2020 01 OO-NSF 11-13354P 0 1
2019 09 OY-HMV 11-13354P 0 0
2019 10 OY-HMV 11-13354P 1 1
2019 11 OY-HMV 11-13354P 0 1
2019 12 OY-HMV 11-13354P 0 1
2020 01 OY-HMV 11-13354P 0 1
Демонстрация по SQLFiddle
Обратите внимание, что если все PeriodYearMonth
интересующие значения присутствуют в vtRelRepComponentsRemovalsByPartNo
вы можете просто использовать SELECT DISTINCT ...
подзапрос для получения этих значений, а не рекурсивный CTE
например
SELECT d.PeriodYearMonth
, rp.Reg
, rp.PartNo
, COALESCE(v.ComponentRemovals, 0) AS ComponentRemovals
, SUM(COALESCE(v.ComponentRemovals, 0)) OVER (PARTITION BY rp.Reg, rp.PartNo ORDER BY d.PeriodYearMonth
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS RunningRemovals
FROM (SELECT DISTINCT PeriodYearMonth FROM vtRelRepComponentsRemovalsByPartNo) d
CROSS JOIN (SELECT DISTINCT Reg, PartNo FROM vtRelRepComponentsRemovalsByPartNo) rp
LEFT JOIN vtRelRepComponentsRemovalsByPartNo v
ON v.PeriodYearMonth = d.PeriodYearMonth
AND v.Reg = rp.Reg
AND v.PartNo = rp.PartNo
ORDER BY rp.Reg, rp.PartNo, d.PeriodYearMonth
Демонстрация по SQLFiddle