运行 总计 SQL Server 2014 上的 over 条款

Running total with over clause on SQL Server 2014

我使用下面的 T-SQL 子查询来计算 运行 总数量RefId

因为我的 table 有超过 2M 的行,我想使用 OVER 子句重写查询。

但我得不到相同的结果;当 CreationDate 对于 RefId 不是唯一的时,结果不正确,因为具有相同日期的前一行被添加到总和中。

是否有获得正确结果的解决方案?

样本数据集:

CREATE TABLE Command 
(
    CreationDate SMALLDATETIME,
    RefId INT,
    Qte INT
);


INSERT INTO Command VALUES('2021-01-10', 100, 10);
INSERT INTO Command VALUES('2021-01-11', 100, 20);
INSERT INTO Command VALUES('2021-01-11', 100, 60);
INSERT INTO Command VALUES('2021-01-11', 100, 10);
INSERT INTO Command VALUES('2021-01-12', 100, 20);
INSERT INTO Command VALUES('2021-01-10', 200, 20);
INSERT INTO Command VALUES('2021-01-11', 200, 10);
INSERT INTO Command VALUES('2021-01-12', 200, 20);
INSERT INTO Command VALUES('2021-01-12', 200, 10);

结果正确的子查询

SELECT 
    c1.*,
    (SELECT SUM(c2.Qte) 
     FROM Command c2
     WHERE c1.RefId = c2.RefId
       AND c2.CreationDate < c1.CreationDate) AS RunninTotal_Qte
FROM 
    Command c1
ORDER BY 
    c1.RefId, c1.CreationDate

使用 OVER 子句重写查询;结果不正确

SELECT 
    c1.*,
    SUM(c1.Qte) OVER (PARTITION BY c1.RefId ORDER BY c1.CreationDate 
                      ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS RunningTotal_Qte
FROM 
    Command c1
ORDER BY 
    c1.RefId, c1.CreationDate

SELECT c1.*,
SUM(c1.Qte) OVER(PARTITION BY c1.RefId ORDER BY c1.CreationDate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as RunningTotal_Qte
FROM Command c1
ORDER BY c1.RefId, c1.CreationDate

如果必须的话,你已经在做的方式无论如何都会更高效,这里是如何只使用 window 函数来做到这一点:

SELECT c1.*,
  SUM(c1.Qte) OVER (PARTITION BY c1.RefId ORDER BY c1.CreationDate) 
    - SUM(c1.Qte) OVER (PARTITION BY c1.RefId, c1.CreationDate ORDER BY c1.CreationDate) AS RunningTotal_Qte
FROM Command c1
ORDER BY c1.RefId, c1.CreationDate