You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL查询:筛选最新状态为4的非活跃设备列表

问题说明

你有一张名为devstatechange的状态变更流水长表,用于全量跟踪设备的状态变化历史,状态枚举定义为:

  • 0:new(新建)
  • 1:setup mode(配置模式)
  • 2:retired(已退役)
  • 3:active(活跃)
  • 4:inactive(非活跃)

设备全年会多次触发激活/停用操作,因此表中持续追加写入状态变更记录,记录自带自增id与状态变更时间戳字段when,表结构与示例数据如下:

id    | device_id | new_state |        when         
 ----------+-----------+-----------+----------------------------
 218010581 |      2505 |         0 | 2022-06-06 16:28:11.174084
 218010580 |      2505 |         1 | 2022-06-06 16:28:11.174084
 218010634 |      2505 |         3 | 2022-06-06 16:29:25.129019
 218087737 |       659 |         3 | 2022-06-07 22:55:48.705208
 218087744 |      1392 |         3 | 2022-06-07 22:55:59.016974
 218087757 |      1556 |         3 | 2022-06-07 22:56:09.811876
 218087758 |      2071 |         1 | 2022-06-07 22:56:20.850095
 218087765 |      2071 |         3 | 2022-06-07 22:56:29.122074

现有可用查询

查询单个指定设备的全量状态变更历史可使用如下语句,按时间正序返回变更记录:

select * 
from devstatechange 
where device_id = 2345 
order by "when";

返回结果示例:

id     | device_id | new_state |            when            
-----------+-----------+-----------+----------------------------
 184682659 |      2345 |         0 | 2021-05-27 17:03:36.894429
 184682658 |      2345 |         1 | 2021-05-27 17:03:36.894429
 184684721 |      2345 |         3 | 2021-05-27 17:31:01.968314
 194933399 |      2345 |         4 | 2021-08-31 23:30:05.555407
 195213746 |      2345 |         3 | 2021-09-03 16:53:39.043005
 206278232 |      2345 |         4 | 2021-12-31 22:30:08.820068
 206515355 |      2345 |         3 | 2022-01-03 16:06:01.223759
 215709888 |      2345 |         4 | 2022-04-30 23:30:30.309389
 215846807 |      2345 |         3 | 2022-05-02 19:40:31.525514

查询设备2351的历史记录同理:

select * 
from devstatechange 
where device_id = 2351 
order by "when";

返回结果示例:

id     | device_id | new_state |            when            
-----------+-----------+-----------+----------------------------
 186091252 |      2351 |         0 | 2021-06-09 15:36:02.775035
 186091253 |      2351 |         1 | 2021-06-09 15:36:02.775035
 186091349 |      2351 |         3 | 2021-06-09 15:37:56.965599
 197880878 |      2351 |         4 | 2021-09-30 23:30:06.691835
 197945073 |      2351 |         3 | 2021-10-01 15:32:35.907913
 208981857 |      2351 |         4 | 2022-01-31 22:30:09.521694
 209722639 |      2351 |         3 | 2022-02-09 15:20:12.412816
 217666572 |      2351 |         4 | 2022-05-31 23:30:30.881928
目标需求

返回去重的设备ID列表,仅保留*每个设备最新时间对应的记录new_state值为4(inactive/非活跃状态)*的设备,过滤掉不符合条件的设备。

按示例数据判断:设备2345和2351都存在3、4状态的反复切换,但2351最新一条记录的状态为4,属于当前非活跃设备,需要纳入结果;2345最新一条记录状态为3,属于活跃设备,需要排除。

已尝试的错误写法

目前试了如下语句,均无法返回正确结果:

SELECT DISTINCT * 
FROM devstatechange 
WHERE MAX("when") AND new_state = 4 
ORDER BY "when";

SELECT DISTINCT device_id, new_state, MAX("when") 
FROM devstatechange 
WHERE new_state = 4  
ORDER BY "when";

已知实现该逻辑可能需要用到分组,但不清楚PostgreSQL中如何实现“取每个设备最新一条记录,再筛选状态为4的设备”的逻辑,需要可落地的实现方案。


内容的提问来源于stack exchange,提问作者the digitalmouse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 04:57:19