运行 缺少日期的总和
Running sum with missing dates
我有一个 table 这样的数据:
PeriodYearMonth Reg PartNo ComponentRemovals RunningRemovals
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 10 OO-NSF 11-13354P 1 1
2019 09 G-NHVR 11-13354P 2 2
2019 10 OY-HMV 11-13354P 1 1
在最后一列中,我计算了 7 个月 运行 每个 PartNo 和每个 Reg 的移除总和。为此,我编写了以下代码:
/****** Find Running Component Removals ******/
SELECT [PeriodYearMonth]
,[Reg]
,[PartNo]
,[ComponentRemovals]
,sum(sum(ComponentRemovals)) over (Partition by [Reg], PartNo Order By PeriodYearMonth, PeriodYearMonth rows between 6 preceding and current row) as RunningRemovals
,[ConfirmedFailures]
, sum(sum(ConfirmedFailures)) over (Partition by [Reg], PartNo Order By PeriodYearMonth, PeriodYearMonth rows between 6 preceding and current row) as RunningFailures
FROM [RALNHVTST].[dbo].[vtRelRepComponentsRemovalsByPartNo]
Group by Reg, PartNo, ComponentRemovals, ConfirmedFailures, PeriodYearMonth
Order by PartNo
但是,由于并非所有月份都包含在 PeriodYearMonth 列中,因此结果不正确。我在网上看到了简单案例的解决方案,但对我来说棘手的部分是,我需要为每个 PartNo、每个 Reg 和每个月输入一个条目。
如有任何帮助,我们将不胜感激。
此致
In the last column I calculated the running sum of removals per PartNo and per Reg over the past 7 months.
删除窗口子句和过滤器:
select [PeriodYearMonth], [Reg], [PartNo], [ComponentRemovals],
sum(sum(ComponentRemovals)) over (Partition by [Reg], PartNo Order By PeriodYearMonth, PeriodYearMonth) as RunningRemovals
[ConfirmedFailures],
sum(sum(ConfirmedFailures)) over (Partition by [Reg], PartNo Order By PeriodYearMonth, PeriodYearMont) as RunningFailures
from [RALNHVTST].[dbo].[vtRelRepComponentsRemovalsByPartNo]
where PeriodYearMonth >= format(dateadd(month, -7, getdate()), 'yyyy MM')
group by Reg, PartNo, ComponentRemovals, ConfirmedFailures, PeriodYearMonth
Order by PartNo
要解决此问题,您需要为所有 PeriodYearMonth
值(使用递归 CTE 生成)以及不同的 Reg
和 [=15= 创建单独的派生 table ] 对,然后 CROSS JOIN
它们相互组合以获得列的所有组合。然后可以将此组合 table LEFT JOIN
编辑为原始 table 以获得每个 Reg
、PartNo
和 PeriodYearMonth
的 ComponentRemovals
],然后可以使用 window 函数对这些求和:
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
请注意,如果 all 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
我有一个 table 这样的数据:
PeriodYearMonth Reg PartNo ComponentRemovals RunningRemovals
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 10 OO-NSF 11-13354P 1 1
2019 09 G-NHVR 11-13354P 2 2
2019 10 OY-HMV 11-13354P 1 1
在最后一列中,我计算了 7 个月 运行 每个 PartNo 和每个 Reg 的移除总和。为此,我编写了以下代码:
/****** Find Running Component Removals ******/
SELECT [PeriodYearMonth]
,[Reg]
,[PartNo]
,[ComponentRemovals]
,sum(sum(ComponentRemovals)) over (Partition by [Reg], PartNo Order By PeriodYearMonth, PeriodYearMonth rows between 6 preceding and current row) as RunningRemovals
,[ConfirmedFailures]
, sum(sum(ConfirmedFailures)) over (Partition by [Reg], PartNo Order By PeriodYearMonth, PeriodYearMonth rows between 6 preceding and current row) as RunningFailures
FROM [RALNHVTST].[dbo].[vtRelRepComponentsRemovalsByPartNo]
Group by Reg, PartNo, ComponentRemovals, ConfirmedFailures, PeriodYearMonth
Order by PartNo
但是,由于并非所有月份都包含在 PeriodYearMonth 列中,因此结果不正确。我在网上看到了简单案例的解决方案,但对我来说棘手的部分是,我需要为每个 PartNo、每个 Reg 和每个月输入一个条目。
如有任何帮助,我们将不胜感激。
此致
In the last column I calculated the running sum of removals per PartNo and per Reg over the past 7 months.
删除窗口子句和过滤器:
select [PeriodYearMonth], [Reg], [PartNo], [ComponentRemovals],
sum(sum(ComponentRemovals)) over (Partition by [Reg], PartNo Order By PeriodYearMonth, PeriodYearMonth) as RunningRemovals
[ConfirmedFailures],
sum(sum(ConfirmedFailures)) over (Partition by [Reg], PartNo Order By PeriodYearMonth, PeriodYearMont) as RunningFailures
from [RALNHVTST].[dbo].[vtRelRepComponentsRemovalsByPartNo]
where PeriodYearMonth >= format(dateadd(month, -7, getdate()), 'yyyy MM')
group by Reg, PartNo, ComponentRemovals, ConfirmedFailures, PeriodYearMonth
Order by PartNo
要解决此问题,您需要为所有 PeriodYearMonth
值(使用递归 CTE 生成)以及不同的 Reg
和 [=15= 创建单独的派生 table ] 对,然后 CROSS JOIN
它们相互组合以获得列的所有组合。然后可以将此组合 table LEFT JOIN
编辑为原始 table 以获得每个 Reg
、PartNo
和 PeriodYearMonth
的 ComponentRemovals
],然后可以使用 window 函数对这些求和:
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
请注意,如果 all 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