1

我有一个包含订单状态更改的表:

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) 但后面没有 S04 和 S05 的每个订单选择 ORDER_ID。

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

我可以在不加入其他表的情况下执行此操作吗?我只想从此表中选择 ORDER_ID。

4

1 回答 1

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
    )
于 2012-10-09T13:51:19.427 回答