运行 总计 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
我使用下面的 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