2011-06-26 35 views
0

我有一個表,看起來像這樣:優化查詢以計算曆史求和值。日期

&ItemNo 
&LocationId 
&MovementDate 
MovementWithinDay 
Stock -- the field I need to update with sum of MovementWithinDay for all older records for same item 

由於此表中包含超過300萬行需要花費很長的時間來填充股票領域。每一行都包含當天內的移動,我需要做的是根據MovementWithinDay的總和來計算這個項目的所有記錄,這個記錄比這個記錄早。這是一次性交易,因此移動到另一個結構是一種選擇。我用光標循環查看記錄,但速度非常慢。對每條記錄總結該項目的所有較舊記錄的查詢速度非常快但非常緩慢。

有沒有人能給我指示在最短的時間內做到這一點?

+2

向我們展示您的查詢 – Magnus

+0

我wrked上simialr問題,在我的博客中描述我的解決方案:反規範化,以執行業務規則:運行總計](HTTP: //sqlblog.com/blogs/alexander_kuznetsov/archive/2009/01/23/denormalizing-to-enforce-business-rules-running-totals.aspx) –

回答

0

所以,從我如何理解您的問題開始,您需要爲每&ItemNo運行MovementWithinDay的總和。我相信你可以使用recursiveCTEwithranking,除非你在SQL Server 2000或更早版本。

這是查詢的外觀:

WITH ranked AS (
    SELECT 
    *, 
    rank = ROW_NUMBER() OVER (PARTITION BY [&ItemNo] ORDER BY MovementWithinDay) 
    FROM 
), 
cumulated AS (
    SELECT 
    [&ItemNo], 
    [&LocationId], 
    [&MovementDate], 
    MovementWithinDay, 
    Stock = MovementWithinDay, 
    rank 
    FROM ranked 
    WHERE rank = 1 
    UNION ALL 
    SELECT 
    r.[&ItemNo], 
    r.[&LocationId], 
    r.[&MovementDate], 
    r.MovementWithinDay, 
    Stock = c.Stock + r.MovementWithinDay, 
    r.rank 
    FROM ranked r 
    INNER JOIN cumulated c ON r.[&ItemNo] = c.[&ItemNo] AND r.rank = c.rank + 1 
) 
SELECT 
    [&ItemNo], 
    [&LocationId], 
    [&MovementDate], 
    MovementWithinDay, 
    Stock = MovementWithinDay 
FROM cumulated 
1

SQL Server確實沒有很好的答案。其他數據庫系統將允許您在日期窗口的分區上編寫分析SUM()函數,但SQL服務器不會。

你最好的選擇可能是一個遊標,很難說。看看at this SQLTeam article.

與自我的問題加入是SQL服務器被重新計算,從以前的所有行的運行總計爲每個行,而不是節約的總使用它來計算下一行的運行總和。