计算SQL Server中的运行月平均值

时间:2017-02-03 23:07:43

标签: sql-server

我们想创建一个数据集,显示我们设备表中的月平均数,按其状态分类:活动,报废,新建。

我越是思考这一点,似乎唯一的方法是首先创建一个容器临时表并使用游标评估每个记录。

这可以在没有临时表的情况下完成吗?

以下内容仅显示我们正在使用的字段:

SELECT a1.statusdate, a1.CreateDate,
RunningTotalActive = count([status]='Active'),
RunningTotalScrapped = count([status]='Scrapped'),
NewEquipment = count(Month(a1.CreateDate) ) 
FROM dbo.Equipment AS a1
INNER JOIN dbo.Equipment AS a2
ON a2.statusdate <= a1.CreateDate
GROUP BY a1.statusdate
ORDER BY a1.statusdate desc

2 个答案:

答案 0 :(得分:0)

我正在为您的数据制作一些SWAG,但我们的想法是按月将这些总和平均为简单计数;使用CTE。

; WITH A AS (
    SELECT a1.statusdate,
    Active = CASE a1.[status] WHEN 'Active' THEN 1 ELSE 0 END,
    Scrapped = CASE a1.[status] WHEN 'Scrapped' THEN 1 ELSE 0 END,
    New = CASE WHEN a2.statusdate = a1.CreateDate THEN 1 ELSE 0 END --Guessing here that "new" means status date and create date are the same
    FROM dbo.Equipment AS a1
    INNER JOIN dbo.Equipment AS a2
    ON a2.statusdate <= a1.CreateDate --"status" can be older than "create" for a piece of equipment? Not sure I understand this criteria. May need sample data.
), B AS (
    SELECT Y = DATEPART(YEAR, statusdate)
    , M = DATEPART(MONTH, statusdate)
    , SumActive = SUM(Active)
    , SumScrapped = SUM(Scrapped)
    , SumNew = SUM(New)
    FROM A
    GROUP BY DATEPART(YEAR, statusdate), DATEPART(MONTH, statusdate)
) 
SELECT Y, M,
    RunningTotalActive = AVG(SumActive)OVER(PARTITION BY Y,M ORDER BY Y,M),
    RunningTotalScrapped = AVG(SumScrapped)OVER(PARTITION BY Y,M ORDER BY Y,M),
    NewEquipment = AVG(SumNew)OVER(PARTITION BY Y,M ORDER BY Y,M)
FROM B;

答案 1 :(得分:0)

你能展示一些样本数据吗? 根据我的理解,我修改了你的脚本。你能试试吗?

    SELECT YEAR(a1.statusdate) AS yr,MONTH(a1.statusdate) AS mon,
           RunningTotalActive = count(CASE WHEN a1.[status]='Active' THEN 1 ELSE NULL END ), -- or SUM(CASE WHEN [status]='Active' THEN 1 ELSE 0 END ),
           RunningTotalScrapped = count(CASE WHEN a1.[status]='Scrapped' THEN 1 ELSE NULL END),
           NewEquipment = count(CASE WHEN YEAR(a1.CreateDate)*12+ MONTH(a1.CreateDate)= YEAR(a1.statusdate)*12+ MONTH(a1.statusdate)) THEN 1 ELSE NULL END )
    FROM dbo.Equipment AS a1
    GROUP BY YEAR(a1.statusdate),MONTH(a1.statusdate) 
    ORDER BY YEAR(a1.statusdate),MONTH(a1.statusdate) DESC