棘手的SQL算法,也许有更好的方法

时间:2013-07-12 22:22:31

标签: sql sql-server tsql

我没有和这个算法结婚,所以随意使用任何想法 - 这个算法只是说明了我想要解决的问题。假设我有一个带有“RecID”,“Value”和“Result”的表。我想将每行的值与其他行相比较。例如:

假设你有一张桌子:

SELECT RecID, Value, Result
INTO #temp
FROM (
SELECT 1 as RecID, 60 as Value, NULL as result
UNION
SELECT 2 as RecID, -30 as Value, NULL as result
UNION
SELECT 4 as RecID, -200 as Value, NULL as result
UNION
SELECT 5 as RecID, -250 as Value, NULL as result
UNION
SELECT 6 as RecID, 300 as Value, NULL as result
) a

1)按照ASC顺序中的 COALESCE(ABS(结果),ABS(值)),ABS(值))对此表进行排序,这样您就可以得到:

RecID, Value, Result
2,     -30,   NULL             
1,     60,    NULL       
4,     -200,  NULL
5,     -250,  NULL
6,     300,   NULL

2)处理ROW1和ROW2:由于值的符号相反(Row1和Row2)从Row1和Row2中取走Row1的值并写入剩余的结果。因此从RecID 1中取出-30并写入结果,并在RecID 2中将值添加-30并写入结果并再次对 COALESCE(ABS(结果),ABS(值)),ABS(值)进行排序)

RecID, Value, Result
2,     -30,   0        <--
1,     60,    30       <--
4,     -200,  NULL
5,     -250,  NULL
6,     300,   NULL

3)处理ROW2和ROW3:由于值的符号相反(Row2和Row3)从RecID 4中取走30(recid 1的结果)并写入结果,从RecID 1中取出相同的30并且写入结果并再次排序 COALESCE(ABS(结果),ABS(值)),ABS(值))

RecID, Value, Result
2,     -30,   0
1,     60,    0        <--
4,     -200,  -170     <--
5,     -250,  NULL
6,     300,   NULL

4)处理ROW3和ROW4:由于(Row3和Row4)值的符号相同,因此无需执行任何操作,因此将值复制到结果并再次对 COALESCE进行排序(ABS(结果),ABS (值)),ABS(值))

RecID, Value, Result
2,     -30,   0
1,     60,    0
4,     -200,  -170     <--
5,     -250,  -250     <--
6,     300,   NULL

5)处理ROW3和ROW4:由于值的符号相反(Row3和Row4)从300中取走-170(recid 4的结果)并写入结果,再次对 COALESCE(ABS(结果),ABS(价值)),ABS(价值))并获得:

RecID, Value, Result
2,     -30,   0
1,     60,    0
4,     -200,  0       <--    
6,     300,   130     <--
5,     -250,  -250  

6)处理ROW4和ROW5:由于值的符号相反(Row4和Row5)从-250拿走130(recid 6的结果)并再次在 COALESCE(ABS(结果),ABS上排序(值)),ABS(值))并得到:

RecID, Value, Result
2,     -30,   0
1,     60,    0
4,     -200,  0
6,     300,   0         <--
5,     -250,  -120      <--

由于具有相反符号的最后一个值已被净化,因此无法再进行净额结算。

只是不确定如何写这样的东西。

1 个答案:

答案 0 :(得分:1)

很好地呈现算法。这一切都归结为:

SELECT sum(values) AS result FROM #temp;

返回-120。或者你想要实现其他目标吗?