【问题标题】:PostgreSQL rank queryPostgreSQL 排名查询
【发布时间】:2013-08-09 01:07:45
【问题描述】:

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

【问题讨论】:

  • 这种“状态何时改变”的查询通常最好通过比较state = lag(state)来完成。

标签: sql postgresql


【解决方案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,从而产生连续编号。

【讨论】:

    猜你喜欢
    • 2021-10-01
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多