SQL基于阈值对记录进行分组的最快方法

时间:2012-07-25 09:52:25

标签: sql-server-2008 tsql

我的记录位于一个有三列的临时表中:

  1. 第1栏:ID(Bigint)
  2. Column2:CreationDateTime(dateTime)
  3. 第3栏:卷(浮动)
  4. 记录根据CreationDateTime进行排序。 我需要从表中选择Sum of Volume等于THRESHOLD1的记录,然后对Threshold2进行相同的记录。

    一种方法是向表中添加一个新列,该列具有以前记录的Volume总和。例如:

    ID - CreationDateTime - 卷 - SUM

    1 - 20/07/2012 - 10 - 10

    2 - 21/07/2012 - 12 - 22

    3 - 22/07/2012 - 7 - 29

    然后选择*来自temp,其中Sum> = Threshold但总和的计算并不是最快的方法。

    我想知道是否有人可以提出更好的方法来做上述事情。

    我正在使用SQL Server 2008,如果需要,我也可以使用CLR。

2 个答案:

答案 0 :(得分:1)

试试这个解决方案:

您可以通过自我加入表格和分组来找到运行总计

with cte as(
select T2.ID, T2.CreationDateTime,SUM(T1.Volume) [SUM]
from test_table T1 join  test_table T2
on T1.id<=T2.id
group by T2.id, T2.CreationDateTime)
select * from cte where [SUM]>= Threshold

答案 1 :(得分:0)

这是一种使用递归CTE的方法,它可能是最快的:

select @i=min(ID) from @temp

;with a as 
( 
    select ID, Volume, Volume as RunningTotal 
    from @temp
    where ID=@i 

    union all 
    select b.ID, b.Volume, b.Volume + a.RunningTotal as RunningTotal 
    from @temp b 
        inner join a 
            on b.ID=a.ID+1 

) 
select * from a 

与运行总计相关的一些链接:

http://www.sqlusa.com/bestpractices/runningtotal/

http://www.databasejournal.com/features/mssql/article.php/3112381/SQL-Server-Calculating-Running-Totals-Subtotals-and-Grand-Total-Without-a-Cursor.htm

http://www.mssqltips.com/sqlservertip/1686/calculate-running-totals-using-sql-server-cross-joins/

http://social.msdn.microsoft.com/Forums/eu/transactsql/thread/1b4d87cb-ec77-4455-af48-bf7dae50ab87

使用函数的计算列:

create function dbo.fn_VolumeRunningTotal 
{ 
    @dt datetime 
} 
returns int 
as  
begin 
    declare @total int 
    select @total = sum(volume) 
    from dbo.MyVolumeTable 
    where CreationDateTime <= @dt 

    return @total 
end 

计算列公式:

dbo.fn_VolumeRunningTotal(CreationDateTime) 

选择陈述:

select * from dbo.MyVolumnTable where RunningTotal <= @Threshold1