TSQL获取历史中具有特定代码的所有订单

时间:2012-10-09 13:35:12

标签: sql tsql sql-server-2005

我有一个表格,用于保存订单的状态更改:

ORDER_ID  |  CHANGE_DATE      |  CODE_1  |  CODE_2  |  CODE_3
=============================================================
1         |  2012-09-01 12:20 |  Z1      |  NULL    |  NULL
1         |  2012-09-01 12:21 |  Z2      |  S01     |  NULL
1         |  2012-09-01 12:22 |  Z2      |  S04     |  NULL
2         |  2012-09-01 12:22 |  Z1      |  S01     |  NULL
3         |  2012-09-01 12:23 |  Z1      |  S03     |  NULL
1         |  2012-09-01 12:24 |  Z1      |  S02     |  NULL
2         |  2012-09-01 12:29 |  Z1      |  S05     |  NULL
1         |  2012-09-01 13:29 |  Z5      |  T01     |  X01
2         |  2012-09-01 13:31 |  Z1      |  T01     |  NULL

我需要为历史CODE_2 IN(S01,S02,S03)中的每个订单选择ORDER_ID,但在它们之后没有S04和S05。

在此特定情况下,查询应返回订单1,因为在CODE_2之后没有S04和S05,请注意订单1在历史记录中有S04,但之后它具有代码S02。 由于代码S03,它也应该返回订单3。 不应该返回订单2,因为他的历史记录中的最后一个代码是S05(最后来自S组)。

我可以在不加入其他桌子的情况下这样做吗?我想只从这个表中选择ORDER_ID。

1 个答案:

答案 0 :(得分:1)

如果CHANGE_DATE实际上是允许对行进行排序的列,那么以下内容就足够了:

declare @T table (ORDER_ID int,CHANGE_DATE datetime,CODE_1 char(2),CODE_2 char(3),CODE_3 char(3))
insert into @T(ORDER_ID,CHANGE_DATE,CODE_1,CODE_2,CODE_3) values
(1,'2012-09-01T12:20:00','Z1',NULL,NULL),
(1,'2012-09-01T12:21:00','Z2','S01',NULL),
(1,'2012-09-01T12:22:00','Z2','S04',NULL),
(2,'2012-09-01T12:20:00','Z1','S01',NULL),
(3,'2012-09-01T12:21:00','Z1','S03',NULL),
(1,'2012-09-01T12:24:00','Z1','S02',NULL),
(2,'2012-09-01T12:29:00','Z1','S05',NULL),
(1,'2012-09-01T13:23:00','Z5','T01','X01'),
(2,'2012-09-01T13:31:00','Z1','T01',NULL)

select distinct ORDER_ID from @T t where CODE_2 in ('S01','S02','S03')
and not exists(
    select * from @T t2 where
        t.ORDER_ID = t2.ORDER_ID and
        t2.CODE_2 in ('S04','S05') and
        t2.CHANGE_DATE > t.CHANGE_DATE
    )