SQL Server查询计算差异。每月指数

时间:2016-03-09 10:14:07

标签: sql sql-server

我有一张这样的表:

Id    Machine        Year     Month       SumProductionPerMonth
==    =======        ====     ======      =============
1     Prod1          2016      1           1500
2     Prod1          2016      2           1800
3     Prod1          2016      3           1900
4     Prod2          2016      1           456
5     Prod2          2016      2           789
6     Prod2          2016      3           922

我得到这样的数据

select table.Id, table.Machine, table.Year, 
table.Month, SUM(index) as SumProductionPerMonth...

我想计算每个月x的SumProductionPerMonth与每台机器的差异:

( SumProductionPerMonth Month N - SumProductionPerMonth Month N-1) 

,并得到如下结果:

Id    Machine        Year     Month       SumProductionPerMonth    Delta
==    =======        ====     ======      =============            ====
1     Prod1          2016      1           1500                     0
2     Prod1          2016      2           1800                     300
3     Prod1          2016      3           1900                     100
4     Prod2          2016      1           456                      0
5     Prod2          2016      2           789                      333
6     Prod2          2016      3           922                      133

如何进行sql server查询以获得此结果?

2 个答案:

答案 0 :(得分:4)

只需使用"窗口聚合函数",LAG

COALESCE(SumProductionPerMonth 
          - LAG(SumProductionPerMonth) -- previous month's value
            OVER (PARTITION BY machine
            ORDER BY year, month), 0)

编辑:

在SQL Server 2012之前,您可以使用ROW_NUMBER加入

WITH cte AS 
 (
   SELECT *
     ,ROW_NUMBER() 
      OVER (PARTITION BY machine ORDER BY YEAR ,MONTH) AS rn
   FROM SourceT
 )
SELECT t1.*
  ,COALESCE(t1.SumProductionPerMonth - prev.SumProductionPerMonth, 0) 
FROM cte AS t1 LEFT JOIN cte AS prev
  ON prev.Machine = t1.Machine
 AND prev.rn = t1.rn -1 

答案 1 :(得分:1)

*您可以在SQL Server 2008 *

上运行此查询
 WITH CTE
    AS (
        SELECT *
            ,RN = ROW_NUMBER() OVER (
                PARTITION BY machine ORDER BY year
                    ,month
                )
            ,(
                ROW_NUMBER() OVER (
                    PARTITION BY machine ORDER BY year
                        ,month
                    )
                ) / 2 rndiv2
            ,(
                ROW_NUMBER() OVER (
                    PARTITION BY machine ORDER BY year
                        ,month
                    ) + 1
                ) / 2 rnplus1div2
        FROM SourceT
        )
    SELECT *
        ,ISNULL(SumProductionPerMonth - (
                CASE 
                    WHEN rn % 2 = 1
                        THEN MAX(CASE 
                                    WHEN rn % 2 = 0
                                        THEN SumProductionPerMonth
                                    END) OVER (
                                PARTITION BY machine
                                ,rndiv2
                                )
                    ELSE MAX(CASE 
                                WHEN rn % 2 = 1
                                    THEN SumProductionPerMonth
                                END) OVER (
                            PARTITION BY machine
                            ,rnplus1div2
                            )
                    END
                ), 0) AS balance_lag
    FROM CTE
    ORDER BY machine
        ,SumProductionPerMonth