【发布时间】:2020-02-11 14:06:18
【问题描述】:
我试图避免使用循环来获得运行总计。这是一个简化版本;真实版本包括几个类别的小计。我知道我可以使用窗口函数 [@Xata2] 来做到这一点,但是如果您将总数限制为非负数(即,如果总数为负数,则使用 0相反)[@Xata3],因为我放置的任何条件都在当前行上,而不是累积总数。
DECLARE @Xata TABLE (
ID INTEGER IDENTITY
, result INTEGER
)
DECLARE @Xata2 TABLE (
ID INTEGER IDENTITY
, result INTEGER
, total INTEGER
)
DECLARE @Xata3 TABLE (
ID INTEGER IDENTITY
, result INTEGER
, total INTEGER
)
DECLARE @result INTEGER
, @total INTEGER
, @Counter INTEGER
INSERT INTO @Xata (result) SELECT ROUND(RAND()* 9 - 4.5, 0)
INSERT INTO @Xata (result) SELECT ROUND(RAND()* 9 - 4.5, 0)
INSERT INTO @Xata (result) SELECT ROUND(RAND()* 9 - 4.5, 0)
INSERT INTO @Xata (result) SELECT ROUND(RAND()* 9 - 4.5, 0)
INSERT INTO @Xata (result) SELECT ROUND(RAND()* 9 - 4.5, 0)
INSERT INTO @Xata (result) SELECT ROUND(RAND()* 9 - 4.5, 0)
INSERT INTO @Xata (result) SELECT ROUND(RAND()* 9 - 4.5, 0)
INSERT INTO @Xata (result) SELECT ROUND(RAND()* 9 - 4.5, 0)
INSERT INTO @Xata (result) SELECT ROUND(RAND()* 9 - 4.5, 0)
INSERT INTO @Xata (result) SELECT ROUND(RAND()* 9 - 4.5, 0)
-- @Xata2: WINDOWING FUNCTION
INSERT INTO @Xata2
SELECT result
, SUM(result) OVER (ORDER BY ID)
FROM @Xata
SELECT ID
, result
, total AS total_x2_neg
FROM @Xata2
SET @Counter = 0
WHILE @Counter < (SELECT MAX(ID) FROM @Xata)
BEGIN
SET @Counter += 1
SELECT @result = result FROM @Xata WHERE ID = @Counter
SET @total = ISNULL((SELECT total FROM @Xata3 WHERE ID = @Counter - 1), 0)
INSERT INTO @Xata3
SELECT @result
, IIF(@result + @total < 0, 0, @result + @total)
END
SELECT ID
, result
, total AS total_x3_noneg
FROM @Xata3
【问题讨论】:
-
你能解释一下你的查询背后的逻辑是什么以及它应该做什么?
-
这是我很久以来见过的最好的复制品。点赞
-
@Nick.McDermaid 我也很欣赏复制品,但我更喜欢修复值来修复输出。如果解决方案正确返回,则在此处使用随机值会使查看变得更加困难...无论如何,从我这边+1。
-
@DaveX 假设第 7 行包含结果
-6。total_x3_noneg应该是0还是5? -
@Menno,我认为第 7 到第 8 行回答了您的问题。我们有一个 1 和
-3的结果,我们看到0。我认为这是:计算减法,但永远不会低于零。
标签: sql-server tsql window-functions