我已经获得了一个查询并尝试找出一种方法来删除光标并保持功能,因为起始表可以进入数百万行。
表格中的数据示例:
ID DollarValue Month RowNumber
1 $10 1/1/2014 1
1 $15 2/1/2014 2
1 -$40 3/1/2014 3
1 $50 4/1/2014 4
2 -$11 1/1/2014 1
2 $11 2/1/2014 2
2 $5 3/1/2014 3
预期结果:
ID DollarValue Month RowNumber TestVal
1 $10 1/1/2014 1 1
1 $15 2/1/2014 2 0
1 -$40 3/1/2014 3 -1
1 $50 4/1/2014 4 1
2 -$11 1/1/2014 1 -1
2 $11 2/1/2014 2 0
2 $5 3/1/2014 3 1
这是光标内部发生的逻辑(伪代码):
If a @ID <> @LastId AND @Month <> @LastMonth
Set @RunningTotal = @DollarValue
Set @LastMonth = '12/31/2099'
Set @LastID = @ID
Set @TestVal = Sign(@DollarValue)
Else
If Sign(@RunningTotal) = Sign(@RunningTotal + @DollarValue)
Set @TestVal = 0
Else
Set @TestVal = Sign(@DollarValue)
Set @RunningTotal = @RunningTotal + @DollarValue
我知道如何将其更改为基于设置?
答案 0 :(得分:2)
您可以使用窗口版SUM
来计算运行总计:
;WITH CTE AS (
SELECT ID, DollarValue, Month, RowNumber,
SUM ( DollarValue ) OVER (PARTITION BY ID ORDER BY RowNumber) as RunningTotal
FROM #mytable
)
SELECT C1.ID, C1.DollarValue, C1.Month, C1.RowNumber,
CASE WHEN C1.RowNumber = 1 THEN SIGN(C1.DollarValue)
WHEN SIGN(C1.RunningTotal) = SIGN(C2.RunningTotal) THEN 0
ELSE SIGN(C1.RunningTotal)
END AS TestVal
FROM CTE AS C1
LEFT JOIN CTE AS C2 ON C1.ID = C2.ID AND C1.RowNumber = C2.RowNumber + 1
在LEFT JOIN
上使用RowNumber
,您可以获取之前的记录,并将当前的运行总计与之前的记录进行比较。然后使用简单的CASE
来应用与运行总计SIGN
中的更改相关的规则。
P.S。似乎上述解决方案在SQL Server 2012之前的版本中不起作用。在这种情况下,CTE
内的运行总计算必须由“常规”版本替换。
答案 1 :(得分:2)
这是2008年的解决方案
WITH CTE AS (
SELECT
AA.[ID]
,AA.[Month]
,AA.[RowNumber]
,AA.[DollarValue]
,SIGN(SUM(BB.[DollarValue])) AS RunTotalSign
FROM YourTable AS AA
LEFT JOIN YourTable AS BB
ON (AA.[ID] = BB.[ID] AND BB.[RowNumber] <= AA.[RowNumber])
GROUP BY AA.[ID],AA.[Month],AA.[DollarValue],AA.[RowNumber])
)
SELECT
AA.[ID]
,AA.[Month]
,AA.[RowNumber]
,AA.[DollarValue]
,CASE WHEN AA.RunTotalSign = CC.RunTotalSign Then 0
ELSE AA.RunTotalSign
END
AS TestVal
FROM CTE AS AA
LEFT JOIN CTE AS CC
ON (AA.[ID] = CC.[ID] AND AA.[RowNumber] = CC.[RowNumber]+1)