我继承了一个存储过程,该过程利用表变量来存储数据,然后使用运行总计算更新每一行。表变量中记录的顺序非常重要,因为我们希望将数量从最高到最低排序(即,当您向下移动时,运行总数将变得越来越大。)
我的问题是,在更新表变量的步骤中,运行总计似乎在计算,但不是表格变量中的数据先前按(按最高音量降序)排序
var text = <%-JSON.stringify({ content: story.Content })%>.content;
结果是,具有最高音量的记录,我预期首先计算的运行总计(因此运行总数= [音量]),不知何故在列表中进一步向下。运行总计似乎随机计算
这是我期望得到的:
但这是代码实际生成的内容:
不确定是否有办法在表变量上设置UPDATE语句,使其按卷desc排序?从我到目前为止所读到的,它可能是一个表变量的排序行为的问题,但不知道如何纠正?有人可以帮忙吗?
答案 0 :(得分:2)
查看SQL中提供的Window函数
例如
Declare @YourTable table (ID int,Volume int)
Insert Into @YourTable values
(100,1306489),
(125,898426),
(150,907404)
Select ID
,Volume
,RunningTotal = sum(Volume) over (Order by Volume Desc)
From @YourTable
Order By Volume Desc
返回
ID Volume RunningTotal
100 1306489 1306489
150 907404 2213893
125 898426 3112319
要明确,@ YourTable仅用于演示目的。不需要将实际数据插入表变量。
编辑支持2008年(好消息是2008年支持Row_Number())
Select ID
,Volume
,RowNr=Row_Number() over (Order by Volume Desc)
Into #Temp
From @YourTable
Select A.ID
,A.Volume
,RunningTotal = sum(B.Volume)
From #Temp A
Join #Temp B on (B.RowNr<=A.RowNr)
Group By A.ID,A.Volume
Order By A.Volume Desc
答案 1 :(得分:1)
GarethD提供了计算跑步总数及其表现的多种方式的权威链接。正确的一个是最简单和最快的, 300倍更快,然后古怪的更新。这是因为它可以利用覆盖排序列的任何索引,并且因为它更简单。
我在这里重复一遍,说明当数据库提供适当的窗口函数时,这是多么简单
SELECT
[Date],
TicketCount,
SUM(TicketCount) OVER (ORDER BY [Date] RANGE UNBOUNDED PRECEDING)
FROM dbo.SpeedingTickets
ORDER BY [Date];
SUM
行表示:如果按日期排序,则对所有(UNBOUNDED)之前的行(PRECEDING)所有票据进行计数
最终比古怪的更新快300倍。
VolumeTable
的等效查询将是:
SELECT
ID,
Volume,
ABS(Volume) as SortValue,
SUM(Volume) OVER (ORDER BY ABS(Volume) DESC RANGE UNBOUNDED PRECEDING)
FROM
VolumeTable
ORDER BY ABS(Volume) DESC
请注意,如果排序列(Volume)上有索引,并且未使用ABS,则速度会快得多。在列上应用任何函数意味着优化器不能使用覆盖它的任何索引,因为实际的排序值与存储在索引中的值不同。
如果表非常大并且性能受损,您可以创建计算列并在其上创建索引