每两行运行计数

MMM*_*MMS 13 sql sql-server sql-server-2012

我试图计算每个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
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

但预期产量:

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
Run Code Online (Sandbox Code Playgroud)

我在这个查询中做错了什么?

注意:SQL Servre版本是2012.

Max*_*rek 16

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
Run Code Online (Sandbox Code Playgroud)

滞后返回前一行的值 - 当row_number()为偶数时,将当前行的值添加到上一行 - 否则,只显示当前行的销售额.通过EmpId对每个进行分区,按yr排序 - 输出与预期匹配.

另外,非常感谢您添加DDL /样本数据.

  • 考虑为你的答案添加一些评论, (2认同)

Gio*_*sos 6

表达方式:

SUM(Sales) OVER (PARTITION BY empid 
                 ORDER BY empid 
                 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
Run Code Online (Sandbox Code Playgroud)

考虑当前行和紧接在它之前的2行计算总和.所以它实际上计算了一个滚动总和,这是你真正不想要的.

我认为你实际上正在寻找以下内容:

;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
Run Code Online (Sandbox Code Playgroud)

上面的查询使用a CTE来计算字段grp:该字段的值1用于empid分区的前两个记录,2用于接下来的两个记录,依此类推.

使用grp我们可以计算sales2组的运行总数,这是OP的要求.

在这里演示

编辑:

为了抵消更大的记录组尝试使用(信用转到@Max Szczurek指出这一点):

(ROW_NUMBER() OVER (PARTITION BY empid ORDER BY yr) - 1 ) / n AS grp
Run Code Online (Sandbox Code Playgroud)

n每个组包含的记录数在哪里.