我在postgreSQL表中有数据如下,
pkid id timestamp isactive
-----------------------------------------
1 1 "2013-08-08 10:10:10" 0
2 1 "2013-08-08 10:11:10" 0
3 1 "2013-08-08 10:12:10" 0
4 1 "2013-08-08 10:13:10" 1
5 1 "2013-08-08 10:14:10" 1
6 1 "2013-08-08 10:15:10" 1
7 1 "2013-08-08 10:16:10" 1
8 1 "2013-08-08 10:17:10" 1
9 1 "2013-08-08 10:18:10" 0
10 1 "2013-08-08 10:19:00" 0
11 2 "2013-08-08 09:10:10" 0
我想获得一个查询,以便在它从活动状态变为非活动状态时获得第一条记录,反之亦然,例如每个ID,
1 1 "2013-08-08 10:10:10" 0
4 1 "2013-08-08 10:13:10" 1
9 1 "2013-08-08 10:18:10" 0
11 2 "2013-08-08 09:10:10" 0
我尝试使用rank()但是它在活动/非活动状态中分配排名值,即rank()(按ID分区,按时间戳排列等效顺序)
pkid id timestamp isactive rank
----------------------------------------------
1 1 "2013-08-08 10:10:10" 0 1
2 1 "2013-08-08 10:11:10" 0 2
3 1 "2013-08-08 10:12:10" 0 3
4 1 "2013-08-08 10:13:10" 1 1
5 1 "2013-08-08 10:14:10" 1 2
6 1 "2013-08-08 10:15:10" 1 3
7 1 "2013-08-08 10:16:10" 1 4
8 1 "2013-08-08 10:17:10" 1 5
9 1 "2013-08-08 10:18:10" 0 4
10 1 "2013-08-08 10:19:00" 0 5
11 2 "2013-08-08 09:10:10" 0 1
我希望看到结果为,
pkid id timestamp isactive rank
---------------------------------------------
1 1 "2013-08-08 10:10:10" 0 1
2 1 "2013-08-08 10:11:10" 0 2
3 1 "2013-08-08 10:12:10" 0 3
4 1 "2013-08-08 10:13:10" 1 1
5 1 "2013-08-08 10:14:10" 1 2
6 1 "2013-08-08 10:15:10" 1 3
7 1 "2013-08-08 10:16:10" 1 4
8 1 "2013-08-08 10:17:10" 1 5
9 1 "2013-08-08 10:18:10" 0 1
10 1 "2013-08-08 10:19:00" 0 2
11 2 "2013-08-08 09:10:10" 0 1
然后我可以选择所有等级== 1并获得状态改变时的时间戳。
答案 0 :(得分:1)
您可以使用lag()
功能执行此操作:
select t.*
from (select t.*,
lag(isactive) over (partition by id order by timestamp) as prevIsActive
from t
) t
where prevIsActive is NULL or prevIsActive <> IsActive;
如果状态仅在一个方向上进行 - 从非活动状态到活动状态,反之亦然,您只能按照建议的方式进行操作。您的方法将所有活动和非活动组合在一起作为id,从而产生连续编号。