2011-08-11 91 views
4

我有一个应用程序将“生产”表中的记录更改记录到“历史记录”表中。历史表基本上是生产表的字段副本的字段,具有诸如上次修改日期,最后修改日期等一些额外列。T-SQL确定历史记录表中的状态更改

这很好,因为我们可以随时获得记录的快照变化。但是,它很难确定记录的唯一状态更改。下面是一个例子。

BoxID StatusID SubStatusID ModifiedTime 
1   4   27  2011-08-11 15:31 
1   4   11  2011-08-11 15:28 
1   4   11  2011-08-10 09:07 
1   5   14  2011-08-09 08:53 
1   5   14  2011-08-09 08:19 
1   4   11  2011-08-08 14:15 
1   4   9  2011-07-27 15:52 
1   4   9  2011-07-27 15:49 
1   2   8  2011-07-26 12:00 

正如你可以在上面表格中看到(数据来源于与简洁和安全删除等领域的真实系统)BoxID 1已经有9名更改生产记录。其中一些更新导致状态发生变化,一些更新不发生,这意味着其他字段(未显示)发生了变化。

我需要能够在TSQL中从这些数据中提取独特的状态变化。给出上面的输入表,我正在寻找的输出如下。

BoxID StatusID SubStatusID ModifiedTime 
1   4   27  2011-08-11 15:31 
1   4   11  2011-08-10 09:07 
1   5   14  2011-08-09 08:19 
1   4   11  2011-08-08 14:15 
1   4   9  2011-07-27 15:49 
1   2   8  2011-07-26 12:00 

这并不容易,因为通过StatusID和SubStatusID分组,并采取min(ModifiedTime)然后加入放回历史表,因为状态可以倒着走,以及(见StatusID 4,SubStatusID 11被设置两次)。

任何帮助将不胜感激!

回答

5

这是否做对你的工作

;WITH Boxes_CTE AS 
    (
    SELECT Boxid, StatusID, SubStatusID, ModifiedTime, 
     ROW_NUMBER() OVER (PARTITION BY Boxid ORDER BY ModifiedTime) AS SEQUENCE 
    FROM Boxes 
    ) 

SELECT b1.Boxid, b1.StatusID, b1.SubStatusID, b1.ModifiedTime 
FROM Boxes_CTE b1 
LEFT OUTER JOIN Boxes_CTE b2 ON b1.Boxid = b2.Boxid 
      AND b1.Sequence = b2.Sequence + 1 
WHERE b1.StatusID <> b2.StatusID 
    OR b1.SubStatusID <> b2.SubStatusID 
    OR b2.StatusID IS NULL 
ORDER BY b1.ModifiedTime DESC 
; 
+0

这个效果非常好。谢谢! – thomas

2
Select BoxID,StatusID,SubStatusID FROM Staty CurrentStaty 
INNER JOIN ON 
(
Select BoxID,StatusID,SubStatusID FROM Staty PriorStaty 
) 
Where Staty.ModifiedTime= 
          (Select Max(PriorStaty.ModifiedTime) FROM PriorStaty 
          Where PriortStaty.ModifiedTime<Staty.ModifiedTime) 
AND Staty.BoxID=PriorStaty.BoxID 
AND NOT (
     Staty.StatusID=PriorStaty.StatusID 
     AND 
     Staty.SubStatusID=PriorStaty.StatusID 
) 
+0

您可以使用{}键或Ctrl-K格式化你的代码。 – bobs

+0

虽然我认为你有语法错误。检查你的INNER JOIN ON – bobs