SQL - 查找同一 ID 的两个连续行

SQL - find two consecutive rows for the same ID

我们有 table 这样的:

ID  PERSON  GROUP  ASSIGNEDGROUP  CHANGEDATE
1   null    GROUP1 GROUP1         01.01.2014
1   NAME1   null   GROUP1         02.01.2014
1   null    GROUP2 GROUP2         03.01.2014
2   null    GROUP1 GROUP1         04.01.2014
2   NAME1   null   GROUP1         05.01.2014
2   null    GROUP2 GROUP2         06.01.2014
2   null    GROUP3 GROUP3         07.01.2014

我们想找到两个连续的行,其中 PERSON 字段的相同 ID 和基于日期字段的值为 null。 (如果 PERSON 字段为空,则 GROUP 字段有值,反之亦然)

因此对于此示例,只应列出最后两行,因为它们具有相同的 ID,并且它们之间的日期是连续的

2   null    GROUP2 GROUP2         06.01.2014
2   null    GROUP3 GROUP3         07.01.2014

我正在尝试编写一些 SQL 语法,但真的不知道如何开始,这可能是一些复杂的表达式。我想首先要做的是根据日期获取两个连续的行,并根据它们检查 PERSON 是否为空。

提前致谢

这是使用lag()lead()的好地方:

select t.*
from (select t.*,
             lag(person) over (partition by id order by changedate) as person_prev,
             lead(person) over (partition by id order by changedate) as person_next
      from table t
     ) t
where person is null and
      (person_prev is null or person_next is null);

编辑:

上面的方法不太有效,因为每个 id 的第一行或最后一行都会返回 NULL。糟糕。这是一个修复方法:

select t.*
from (select t.*,
             lag(person) over (partition by id order by changedate) as person_prev,
             lead(person) over (partition by id order by changedate) as person_next,
             lag(id) over (partition by id order by changedate) as id_prev,
             lead(id) over (partition by id order by changedate) as id_next
      from table t
     ) t
where person is null and
      ((person_prev is null and id_prev is not null) or
       (person_next is null and id_next is not null)
      );

编辑二;

寻找两个非空的组如何?

select t.*
from (select t.*,
             lag(group) over (partition by id order by changedate) as group_prev,
             lead(group) over (partition by id order by changedate) as group_next
      from table t
     ) t
where group is not null and
      (group_prev is not null or group_next is not null);

注意:group 是一个非常糟糕的列名,因为它是 SQL 保留字。