[英]SQL - find two consecutive rows for the same ID
We have table like this: 我们有这样的表:
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
We would like to find two consecutive rows where PERSON field will have value null for the same ID and based on the date field. 我们想找到两个连续的行,其中PERSON字段将基于日期字段具有相同ID的空值。 (if PERSON field is null then GROUP field has value and vice verse)
(如果PERSON字段为null,则GROUP字段具有值,反之亦然)
So for this example only last two rows should be listed because they are for the same ID and dates between them are consecutive 因此,对于此示例,仅应列出最后两行,因为它们具有相同的ID,并且它们之间的日期是连续的
2 null GROUP2 GROUP2 06.01.2014
2 null GROUP3 GROUP3 07.01.2014
I am trying to write some SQL syntax but really do not know how to start, this probably is some complex expression. 我正在尝试编写一些SQL语法,但实际上不知道如何开始,这可能是一些复杂的表达式。 I suppose first thing to do is to get two consecutive rows based on dates and on them to check if PERSON is null.
我想要做的第一件事是根据日期获取两个连续的行,并根据它们检查PERSON是否为空。
Thank you in advance 先感谢您
This is a good place to use lag()
and lead()
: 这是使用
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);
EDIT: 编辑:
The above doesn't quite work because NULL
will be returned for the first or last row for each id
. 上面的方法不太有效,因为将为每个
id
的第一行或最后一行返回NULL
。 Ooops. 糟糕! Here is one fix:
这是一个解决方法:
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)
);
EDIT II; 编辑II;
How about looking for two groups that are 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);
Note: group
is a very bad name for a column, because it is a SQL reserved word. 注意:
group
是列的非常不好的名称,因为它是SQL保留字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.