优化查询以计算历史求和值pr。日期

时间:2011-06-26 13:18:31

标签: sql sql-server query-optimization

我有一张看起来像这样的表:

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

由于此表包含超过3亿行,因此填充Stock字段需要很长时间。每行包含当天的移动,我需要做的是根据此项目的所有记录的MovementWithinDay的总和来计算库存,这些记录早于此记录。这是一次性交易,因此进入另一个结构是一种选择。我已经使用光标循环记录,但速度非常慢。查询总结了每个记录中该项目的所有旧记录,但速度相当快,但速度很慢。

有人能指点我在最短的时间内完成这项工作吗?

2 个答案:

答案 0 :(得分:1)

SQL Server真的没有好的答案。其他数据库系统允许您在由日期窗口划分的分区上编写分析SUM()函数,但SQL服务器不会。

您最好的选择可能是一个光标,伤心地说。看看at this SQLTeam article.

自联接的问题是SQL服务器正在重新计算每个行的所有先前行的运行总计,而不是保存总计并使用它来计算下一行的运行总计。< / p>

答案 1 :(得分:0)

因此,根据我对您的问题的理解,您希望每MovementWithinDay次运行&ItemNo的总和。我相信您可以使用recursive CTE with ranking,除非您使用的是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