查询以查找 "out of sequence" 行

Query to find "out of sequence" rows

我的 table 看起来类似于以下内容:

ID_1 | ID_2 | STATUS   | STATUS_TIME | STATUS_BY
------------------------------------------------
1111 | 2222 | 'ONE'    | [timestamp] | 'USER_1'
3333 | 4444 | 'ONE'    | [timestamp] | 'USER_2'
1111 | 2222 | 'THREE'  | [timestamp] | 'USER_3'
3333 | 4444 | 'TWO'    | [timestamp] | 'USER_2'
3333 | 4444 | 'THREE'  | [timestamp] | 'USER_4'

本质上,这个 table 跟踪 ID_1 和 ID_2 所属的特定项目的状态变化。 ID_1 可能有很多行是ID,但它连接到同一个主要对象。 ID_2 也可能有很多行适用。

因此,要正确匹配两行,您应该检查 ID_1 和 ID_2 是否相同。我遇到的问题是由于一些设计不良的软件我们无法调整或摆脱(无论出于何种原因)。

状态更新通常没有任何特定顺序,但例如在这种情况下,特定 ID_1 + ID_2 对的状态为“一”后应为状态“二” .有些用户跳过了这一步,所以我想看看谁在跳过它。理想情况下,我希望此查询如何工作:

在上面的示例中,我想要以下行:

ID_1 | ID_2 | STATUS   | STATUS_TIME | STATUS_BY
------------------------------------------------
1111 | 2222 | 'THREE'  | [timestamp] | 'USER_3'

我非常希望我说得足够清楚,如果我遗漏了什么,请发表评论。这是在 IBM 的 DB2 版本 9.7 Fix Pack 7 上。我当前的 'solution' 冗长且无法正常运行,因为它列出了 ID_1 + ID_2 上使用 ONE 的所有用户,即使他们中的一些人使用了两个,而另一些人则没有。任何指导或帮助都很棒。

SELECT distinct ID_1, Status_By from table t -- only one user by id_1
WHERE status !<>'ONE' -- is not the first row
AND not exists
(select 1 from table t0 where t0.id_1=t.id_1 and t0.id_2=t.id_2 and t0.status_time<t.status_time  and status <> 'ONE') -- is the  row that follows
and status <> 'TWO' -- and the status is not 'TWO'

这应该适用于您的条件 1 和 2,不确定您的条件 3 是什么意思,因为您说不需要考虑。如果第三个条件也需要测试,那么可以添加一个 "union all"

您可以使用分析函数 LAG()(或 LEAD())查找乱序记录。

根据实际数据,这两种方法中的任何一种都应该有效。

此查询 returns 前面没有 'TWO' 的 'THREE' 条记录:

select * from (
 select 
   t.*, 
   lag(status) over (partition by id_1, id_2 order by status_time) as prev_status 
 from test t
) t1 where status = 'THREE' and prev_status != 'TWO'

备选 returns 'ONE' 记录后面没有 'TWO':

select * from (
 select 
  t.*, 
  lead(status) over (partition by id_1, id_2 order by status_time) as next_status 
 from test t
) t1 where status = 'ONE' and next_status != 'TWO'

如果您需要在前一行(或下一行之后)的行中查找值,请指定偏移量:LAG(status, 2)(或LEAD(status, 2))。