我会稍微改变你的设置。
首先,有一个表格,列出所有感兴趣的产品密钥......
CREATE TABLE product (
product_key INT NOT NULL,
price INT,
some_fact_data VARCHAR(MAX),
what_ever_else SOMEDATATYPE,
PRIMARY KEY CLUSTERED (product_key)
)
然后,我会有一个日历表,其中包含您可能需要报告的每个日期......
CREATE TABLE calendar (
date SMALLDATETIME,
is_bank_holdiday INT,
what_ever_else SOMEDATATYPE,
PRIMARY KEY CLUSTERED (date)
)
最后,我会确保您的数据表在所有相关字段上都有一个覆盖索引......
CREATE INDEX IX_product_day ON #ORDER_TURNOVER (product_key, day_key)
这将允许以下查询...
SELECT
product.product_key,
product.price,
calendar.date,
SUM(price) AS RSum
FROM
product
CROSS JOIN
calendar
INNER JOIN
#ORDER_TURNOVER AS data
ON data.product_key = product.product_key
AND data.day_key > dateadd(mm, -12, calendar.date)
AND data.day_key <= calendare.date
GROUP BY
product.product_key,
product.price,
calendar.date
通过以这种方式执行所有操作,每个 product/calendar_date 组合将与数据表中的一组记录相关,这些记录彼此连续。对于优化器来说,这将使查找要聚合的数据的行为变得更加简单。
[需要一个索引,特别是在顺序(产品、日期)中。]
如果你有相反的索引,它实际上要困难得多......
示例数据:
product | date date | product
---------+------------- ------------+---------
A | 01/01/2012 01/01/2012 | A
A | 02/01/2012 01/01/2012 | B
A | 03/01/2012 02/01/2012 | A
B | 01/01/2012 02/01/2012 | B
B | 02/01/2012 03/01/2012 | A
B | 03/01/2012 03/01/2012 | B
在左侧 oyu 中,只需获取 365 天块中彼此相邻的所有记录。
在右侧搜索每条记录,然后才能进行聚合。搜索相对简单,但你做了 365 个。比左边的版本要多得多。