MS SQL - 实现循环的最佳方式

时间:2013-01-10 07:44:41

标签: sql sql-server optimization stored-procedures

现有对象和内容

有一个名为history_master的表,每次更新名为master的特定表时都会记录该表。它就像一张主表的历史。主表仅包含最新数据

举一个内容的例子

主表


| id | item no| valid from | valid till | 
| 1  | 1      | 2012-12-25 | 2012-12-31 | 
| 2  | 1      | 2013-01-01 | 2013-04-30 |
| 3  | 2      | 2013-01-10 | 2013-12-31 |

history_master看起来像

| id | item no | valid from | valid till | update date |
| 1  |   1     | 2012-01-01 | 2012-06-30 | 2012-02-01  |
| 2  |   1     | 2012-07-01 | 2012-12-31 | 2012-02-01  |
| 3  |   1     | 2012-01-01 | 2012-06-30 | 2012-05-01  |
| 4  |   1     | 2012-07-01 | 2012-11-30 | 2012-05-01  |
| 5  |   1     | 2012-12-01 | 2012-12-31 | 2012-05-01  |
| 6  |   1     | 2012-07-01 | 2012-11-30 | 2012-08-01  |
| 7  |   1     | 2012-12-01 | 2012-12-24 | 2012-08-01  |
| 8  |   1     | 2012-12-25 | 2012-12-31 | 2012-08-01  |

手头的任务:编写一个存储过程,从历史记录中获取项目的所有可用数据,保留最新数据,即结果应如下所示

| item no | valid from | valid till | history_id |
|   1     | 2012-12-25 | 2012-12-31 | 8          |
|   1     | 2012-12-01 | 2012-12-24 | 7          |
|   1     | 2012-07-01 | 2012-11-30 | 6          |
|   1     | 2012-01-01 | 2012-06-30 | 3          |

我想到的逻辑是从历史表中确定批次。对于例如更新日期为2012-08-01的记录将具有批次= 3,2012-05-01将具有批次= 2,最后一次为批次= 1

从最新(3)到最旧(1)开始迭代所有批次,比较日期范围并确定结果,记住最新集合的数据将始终具有优先权。

我能想到的唯一实现方法是WHILE LOOP,我不确定它是否是最佳方式。

历史记录母版包含截至目前的10155734条记录。请建议

1 个答案:

答案 0 :(得分:0)

我想你想把更新日期放到像这样的临时表中

select distinct [update date], identity(int, 1,1) history_id 
into #updatedates
order by [update date]

这给你一个像这样的表

update date history_id
2012-08-01  1
2012-09-01  2
2012-10-01  3

然后将其与原始表格连接以获得结果

select mh.[item no], mh.[vaild from], mh.[valid to], u.history_id
from master_history mh join #updatedates u on mh.[update date] = u.[update date]