我们有这样的表:
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字段为null,则GROUP字段具有值,反之亦然)
因此,对于此示例,只应列出最后两行,因为它们用于相同的ID,并且它们之间的日期是连续的
2 null GROUP2 GROUP2 06.01.2014
2 null GROUP3 GROUP3 07.01.2014
我正在尝试编写一些SQL语法,但实际上不知道如何启动,这可能是一些复杂的表达式。我想首先要做的是根据日期获得两个连续的行,然后检查PERSON是否为空。
提前谢谢
答案 0 :(得分:1)
这是一个使用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);
编辑:
上述内容并不常用,因为每个NULL
的第一行或最后一行都会返回id
。糟糕!这是一个修复:
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)
);
编辑II;
如何寻找两个非空的组?
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保留字。