Sql 缺少日期的运行总和
我有这样一个数据表:Sql 缺少日期的运行总和,sql,sql-server,date,cumulative-sum,Sql,Sql Server,Date,Cumulative Sum,我有这样一个数据表: 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
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个月连续清除量之和。为此,我编写了以下代码:
/****** 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和每个月输入一个条目
任何帮助都将不胜感激
问候
在最后一列中,我计算了过去7个月内每个PartNo和每个Reg的清除量的运行总和
删除windowing子句和筛选器:
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
和PartNo
对创建单独的派生表,并将它们相互交叉连接以获得列的所有组合。然后,可以将此组合表左连接到原始表,以获得每个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
值都出现在vtrerepcomponentsremovalsbypartno
中,则只需使用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
您使用的是哪种dbms?构建并填充一个包含所有年度月份的表格。请将其加入您的查询。谢谢您的回复,但这并不能解决我的问题。我应该说是7个月的连续金额,而不是“过去7个月”。@CathalClavie。这是相当含糊的。原来的措辞听起来很像过去的七个月。非常感谢!我得到一个错误:“无法解决concat操作中“Latin1_General_CS_AS”和“Latin1_General_CI_AS”之间的排序规则冲突。”我以前遇到过这种情况,但我不知道如何解决它。在concat操作中,我只看到一个colum(PeriodYearMonth)。你知道我还需要改变什么变量来解决这个问题吗?你可以忽略它。我通过整理外话解决了这个问题。@CathalClavie很抱歉,我没有时间回答你的评论,但我很高兴你自己找到了答案,这给了你想要的结果。
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