1

我在 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 并获取状态更改时的时间戳。

4

1 回答 1

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,从而产生连续编号。

于 2013-08-09T01:30:35.313 回答