2017-03-29 35 views
12

我試圖計算運行計數爲每2行類似下面,動態計數每2行

CREATE TABLE sales 
(
    EmpId INT, 
    Yr INT, 
    Sales DECIMAL(8,2) 
) 

INSERT INTO sales (EmpId, Yr, Sales) 
VALUES (1, 2005, 12000), (1, 2006, 18000), (1, 2007, 25000), 
     (1, 2008, 25000), (1, 2009, 25000), 
     (2, 2005, 15000), (2, 2006, 6000), (2, 2007, 6000) 

SELECT 
    EmpId, Yr, sales, 
    SUM(Sales) OVER (PARTITION BY empid ORDER BY empid ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS TotalSales2 
FROM 
    sales 

輸出:

EmpId Yr  sales TotalSales2 
----------------------------------- 
    1  2005 12000  12000 
    1  2006 18000  30000 
    1  2007 25000  55000 
    1  2008 25000  68000 
    1  2009 25000  75000 
    2  2005 15000  15000 
    2  2006  6000  21000 
    2  2007  6000  27000 

但預期輸出:

EmpId Yr  Sales TotalSales2 
----------------------------------- 
    1  2005 12000 12000 
    1  2006 18000 30000 
    1  2007 25000 25000 
    1  2008 25000 50000 
    1  2009 25000 25000 
    2  2005 15000 15000 
    2  2006  6000 21000 
    2  2007  6000 6000 

我在這個查詢中做錯了什麼?

注意:SQL Servre的版本是2012年

回答

5

表達:

SUM(Sales) OVER (PARTITION BY empid 
       ORDER BY empid 
       ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) 

計算考慮當前行和2行緊接其前的總和。所以它實際上是計算滾動總和,這是你真正不想要的。

我想你實際上是在尋找類似以下內容:該字段的值是1前兩個記錄的:

;WITH CTE_Group AS (
    SELECT EmpId, Yr, sales,   
      (ROW_NUMBER() OVER (PARTITION BY empid ORDER BY yr) + 1)/2 AS grp 
    FROM sales  
) 
SELECT EmpId, Yr, sales, 
     SUM(sales) OVER (PARTITION BY empid, grp 
         ORDER BY yr) AS TotalSales2 
FROM CTE_Group 

上面的查詢,以便計算領域grp使用CTEempid分區,2爲下兩條記錄,依此類推。

使用grp我們可以根據OP的要求計算2組的運行總數sales

Demo here

編輯:

以抵消更大的組記錄嘗試使用(歸功於@Max Szczurek指出這一點):

(ROW_NUMBER() OVER (PARTITION BY empid ORDER BY yr) - 1)/n AS grp 

其中n是多少記錄每個組的內容。

+0

建議改變(ROW_NUMBER)OVER(PARTITION(BY EMPID ORDER BY年)+ 1)/ 2 AS GRP - 改變1爲-1,然後這適用於較大的組的大小。 +1適用於組大小爲2的組,但在錯誤的方向上偏移較大的組! –

+0

如果我想查找每個EmpId的前12行和另12行的運行總數,我該怎麼辦? – MMMMS

+0

@MaxSzczurek謝謝,這是非常有用的。 –

15
SELECT EmpId, Yr, Sales, 
    CASE WHEN ROW_NUMBER() OVER (PARTITION BY EmpId ORDER BY yr) % 2 = 0 
    THEN sales + lag(sales, 1, 0) OVER (PARTITION BY empid ORDER BY yr) 
    ELSE sales 
    END AS TotalSales2 
FROM sales 

滯後返回上一行的價值 - 當ROW_NUMBER()爲偶數,當前行的值添加到前一列 - 否則,只顯示當前行的銷售額。按EmpId分區,按yr排序 - 輸出與預期相符。

此外,非常感謝您添加DDL /樣本數據。

+2

考慮加入一些評論你的答案, –

+0

我的壞!添加了一些筆記。 –

+0

thats awsome。但我不知道你的問題。如果我想爲每個12行找到運行計數,我該怎麼辦? – MMMMS

2

雖然答案已經被接受,但也請考慮下面的查詢。這將給所需的輸出:

DECLARE @sales TABLE(EmpId INT, Yr INT, Sales DECIMAL(8,2)) 

INSERT INTO @sales (EmpId, Yr, Sales) 
VALUES (1, 2005, 12000), 
     (1, 2006, 18000), 
     (1, 2007, 25000), 
     (1, 2008, 25000), 
     (1, 2009, 25000), 
     (2, 2005, 15000), 
     (2, 2006, 6000), 
     (2, 2007, 6000) 
;WITH SAMPLE_DATA 
AS 
(
SELECT ROW_NUMBER()over(partition by empid order by (select 100))SNO,* FROM  @Sales 
) 
SELECT EmpId,Yr,Sales 
    ,CASE WHEN (SNO%2=0) 
    THEN SALES+ 
    (
     SELECT Sales FROM SAMPLE_DATA T2 WHERE T2.EmpId=T1.EmpId AND  T2.SNO=T1.SNO-1 
    ) 
    ELSE Sales END 
TotalSales2 
FROM SAMPLE_DATA T1 

輸出

-------------------------------------- 
--EmpId Yr Sales TotalSales2 
-------------------------------------- 
1 2005 12000.00 12000.00 
1 2006 18000.00 30000.00 
1 2007 25000.00 25000.00 
1 2008 25000.00 50000.00 
1 2009 25000.00 25000.00 
2 2005 15000.00 15000.00 
2 2006 6000.00  21000.00 
2 2007 6000.00  6000.00 
--------------------------------------