2010-01-22 25 views
2

我们具有的结构类似交易的表如下:高性能的方式来获得运行总量的最大值TSQL

TranxID int (PK and Identity field) 
ItemID  int 
TranxDate datetime 
TranxAmt money 

TranxAmt可正可负,所以运行总计这一领域的(对于任何ItemID)随着时间的推移会上下移动。获取当前总数显然很简单,但我所追求的是获得运行总数和TranxDate最高价值的高性能方式。请注意,TranxDate不是唯一的,并且由于某些回溯,对于给定项目,ID字段不一定与TranxDate的顺序相同。
目前,我们正在做这样的事情(@tblTranx是只包含某个商品的交易表变量):

SELECT Top 1 @HighestTotal = z.TotalToDate, @DateHighest = z.TranxDate 
FROM 
    (SELECT a.TranxDate, a.TranxID, Sum(b.TranxAmt) AS TotalToDate 
    FROM @tblTranx AS a 
    INNER JOIN @tblTranx AS b ON a.TranxDate >= b.TranxDate 
    GROUP BY a.TranxDate, a.TranxID) AS z 
ORDER BY z.TotalToDate DESC 

(该TranxID分组时造成的重复的日期值问题)

对于一个项目,这发生时会给我们HighestTotal和TranxDate。我们只会在应用程序更新相关条目并在另一个表中记录值以便在报告中使用时计算此值,而不是在数万条条目上运行。

问题是,这是否可以以更好的方式完成,以便我们能够在不陷入RBAR陷阱(某些ItemID具有数百个条目)的情况下即时计算出这些值(对于多个项目一次)。如果是这样,那么是否可以调整以获取交易子集的最高值(基于上面未包括的TransactionTypeID)。我目前正在使用SQL Server 2000来完成这项工作,但SQL Server 2008将很快在这里接管,因此可以使用任何SQL Server技巧。

回答

3

SQL Server在计算跑步总数时很糟糕。

这里是您非常查询溶液(按日期群体哪个):

WITH q AS 
     (
     SELECT TranxDate, SUM(TranxAmt) AS TranxSum 
     FROM t_transaction 
     GROUP BY 
       TranxDate 
     ), 
     m (TranxDate, TranxSum) AS 
     (
     SELECT MIN(TranxDate), SUM(TranxAmt) 
     FROM (
       SELECT TOP 1 WITH TIES * 
       FROM t_transaction 
       ORDER BY 
         TranxDate 
       ) q 
     UNION ALL 
     SELECT DATEADD(day, 1, m.TranxDate), 
       m.TranxSum + q.TranxSum 
     FROM m 
     CROSS APPLY 
       (
       SELECT TranxSum 
       FROM q 
       WHERE q.TranxDate = DATEADD(day, 1, m.TranxDate) 
       ) q 
     WHERE m.TranxDate <= GETDATE() 
     ) 
SELECT TOP 1 * 
FROM m 
ORDER BY 
     TranxSum DESC 
OPTION (MAXRECURSION 0) 

需要会对TranxDate指数这个工作快。