SQL 服务器 运行 达到或超过总数时与 dbmail 的总数
SQL Server running total with dbmail when total met or exceeded
我可以通过脚本获得 运行 总数——但我似乎做不到的是隔离我达到或超过某个值的线...
SELECT
column1,
(SELECT SUM(column1) FROM table WHERE column2 <= t1.column2)
FROM
table t1
最终我想做的是创建一个触发器,当 column1 的总和达到或超过 (n) 时发送 dbmail...帮助我 obi-wan
在 SQL-Server 2008 上,您可以使用下一个解决方案:
DECLARE @TBL TABLE(id int, amount int);
INSERT INTO @TBL VALUES
(1, 100), (2, 100), (3, 60), (4, 200), (5, 100);
SELECT t1.ID, t1.amount, SUM(t2.amount) as CumTotal
FROM @TBL t1
CROSS APPLY (SELECT *
FROM @TBL
WHERE ID <= t1.id) t2
GROUP BY t1.ID, t1.amount
HAVING SUM(t1.amount) < 300
ORDER BY t1.ID
;
这是结果:
ID | amount | CumTotal
-: | -----: | -------:
1 | 100 | 100
2 | 100 | 200
3 | 60 | 260
dbfiddle here
虽然这个方案效果不错,但从性能上来说并不推荐。
在这种情况下,最好的选择是使用 CURSOR。
DECLARE @CS table (id int, amount int, total int);
DECLARE @id int, @amount int;
DECLARE @CumSum int = 0;
DECLARE c CURSOR
LOCAL STATIC FORWARD_ONLY READ_ONLY
FOR SELECT ID, amount
FROM @TBL
ORDER BY [id];
OPEN c;
FETCH NEXT FROM c INTO @id, @amount
WHILE @@FETCH_STATUS = 0 AND @CumSum + @amount < 300
BEGIN
SET @CumSum = @CumSum + @amount;
INSERT @CS (id, amount, total)
SELECT @id, @amount, @CumSum;
FETCH NEXT FROM c INTO @id, @amount
END
CLOSE c;
DEALLOCATE c;
SELECT id, amount, total
FROM @CS
ORDER BY id;
GO
id | amount | total
-: | -----: | ----:
1 | 100 | 100
2 | 100 | 200
3 | 60 | 260
dbfiddle here
下一个答案可用于SQL-SERVER 2012及以上
您可以使用 WINDOW 函数和 SUM() ROWS UNBOUNDED PRECEDING 来计算累加和。
看看MS docs。
DECLARE @TBL TABLE(id int, amount int);
INSERT INTO @TBL VALUES
(1, 100), (2, 100), (3, 60), (4, 200), (5, 100);
下次查询returns一个累计和:
SELECT ID,
SUM(amount) OVER (ORDER BY ID ROWS UNBOUNDED PRECEDING) AS CumTotal
FROM @TBL
;
ID | CumTotal
-: | -------:
1 | 100
2 | 200
3 | 260
4 | 460
5 | 560
问题是你不能阻止它,你需要计算所有记录,然后你可以应用一个where子句来过滤记录。
WITH CSum As
(
SELECT ID,
SUM(amount) OVER (ORDER BY ID ROWS UNBOUNDED PRECEDING) AS CumTotal
FROM @TBL
)
SELECT ID, CumTotal
FROM CSum
WHERE CumTotal < 300
ORDER BY ID
;
这是最终结果:
ID | CumTotal
-: | -------:
1 | 100
2 | 200
3 | 260
dbfiddle here
我可以通过脚本获得 运行 总数——但我似乎做不到的是隔离我达到或超过某个值的线...
SELECT
column1,
(SELECT SUM(column1) FROM table WHERE column2 <= t1.column2)
FROM
table t1
最终我想做的是创建一个触发器,当 column1 的总和达到或超过 (n) 时发送 dbmail...帮助我 obi-wan
在 SQL-Server 2008 上,您可以使用下一个解决方案:
DECLARE @TBL TABLE(id int, amount int); INSERT INTO @TBL VALUES (1, 100), (2, 100), (3, 60), (4, 200), (5, 100); SELECT t1.ID, t1.amount, SUM(t2.amount) as CumTotal FROM @TBL t1 CROSS APPLY (SELECT * FROM @TBL WHERE ID <= t1.id) t2 GROUP BY t1.ID, t1.amount HAVING SUM(t1.amount) < 300 ORDER BY t1.ID ;
这是结果:
ID | amount | CumTotal -: | -----: | -------: 1 | 100 | 100 2 | 100 | 200 3 | 60 | 260
dbfiddle here
虽然这个方案效果不错,但从性能上来说并不推荐。
在这种情况下,最好的选择是使用 CURSOR。
DECLARE @CS table (id int, amount int, total int); DECLARE @id int, @amount int; DECLARE @CumSum int = 0; DECLARE c CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY FOR SELECT ID, amount FROM @TBL ORDER BY [id]; OPEN c; FETCH NEXT FROM c INTO @id, @amount WHILE @@FETCH_STATUS = 0 AND @CumSum + @amount < 300 BEGIN SET @CumSum = @CumSum + @amount; INSERT @CS (id, amount, total) SELECT @id, @amount, @CumSum; FETCH NEXT FROM c INTO @id, @amount END CLOSE c; DEALLOCATE c; SELECT id, amount, total FROM @CS ORDER BY id;
GO
id | amount | total -: | -----: | ----: 1 | 100 | 100 2 | 100 | 200 3 | 60 | 260
dbfiddle here
下一个答案可用于SQL-SERVER 2012及以上
您可以使用 WINDOW 函数和 SUM() ROWS UNBOUNDED PRECEDING 来计算累加和。
看看MS docs。
DECLARE @TBL TABLE(id int, amount int); INSERT INTO @TBL VALUES (1, 100), (2, 100), (3, 60), (4, 200), (5, 100);
下次查询returns一个累计和:
SELECT ID, SUM(amount) OVER (ORDER BY ID ROWS UNBOUNDED PRECEDING) AS CumTotal FROM @TBL ;
ID | CumTotal -: | -------: 1 | 100 2 | 200 3 | 260 4 | 460 5 | 560
问题是你不能阻止它,你需要计算所有记录,然后你可以应用一个where子句来过滤记录。
WITH CSum As ( SELECT ID, SUM(amount) OVER (ORDER BY ID ROWS UNBOUNDED PRECEDING) AS CumTotal FROM @TBL ) SELECT ID, CumTotal FROM CSum WHERE CumTotal < 300 ORDER BY ID ;
这是最终结果:
ID | CumTotal -: | -------: 1 | 100 2 | 200 3 | 260
dbfiddle here