基于特定条件检索PostgreSQL表中entity_id的SQL查询需求
PostgreSQL查询:筛选符合特定阶段变更规则的entity_id
表结构
CREATE TABLE entity_changes ( entity_id INTEGER, raw_time BIGINT, resolved_datetime TIMESTAMP WITH TIME ZONE, old_phase VARCHAR(255), new_phase VARCHAR(255) );
该表用于跟踪实体的阶段变更历史,每行记录对应一个实体的一次阶段切换,包含时间信息及变更前后的阶段。
查询需求
需检索满足以下条件的entity_id:
- 存在
new_phase为'Accept'的变更记录; - 同一
entity_id在该Accept变更之后,不存在从'Accept'到'Review'的后续变更。
示例数据
| entity_id | raw_time | resolved_datetime | old_phase | new_phase |
|---|---|---|---|---|
| 1 | 1683722752681 | 2023-05-10T14:45:52.681+02 | NULL | Log |
| 1 | 1683722755440 | 2023-05-10T14:45:55.44+02 | Log | Approve |
| 1 | 1683722758915 | 2023-05-10T14:45:58.915+02 | Approve | Fulfill |
| 1 | 1687773706503 | 2023-06-26T12:01:46.503+02 | Fulfill | Accept |
| 1 | 1687774413272 | 2023-06-26T12:13:33.272+02 | Accept | Review |
| 2 | 1683722752681 | 2023-05-10T14:45:52.681+02 | NULL | Log |
| 2 | 1683722755440 | 2023-05-10T14:45:55.44+02 | Log | Approve |
| 2 | 1683722758915 | 2023-05-10T14:45:58.915+02 | Approve | Accept |
| 2 | 1687773706503 | 2023-06-26T12:01:46.503+02 | Accept | Review |
| 2 | 1687774413272 | 2023-06-26T12:13:33.272+02 | Review | Accept |
根据示例数据,应返回entity_id=2——因为entity_id=1在Accept变更后存在后续的Accept→Review变更,不符合要求。
解决方案SQL
SELECT DISTINCT ec.entity_id FROM entity_changes ec WHERE ec.new_phase = 'Accept' AND NOT EXISTS ( SELECT 1 FROM entity_changes ec2 WHERE ec2.entity_id = ec.entity_id AND ec2.old_phase = 'Accept' AND ec2.new_phase = 'Review' AND ec2.resolved_datetime > ec.resolved_datetime );
逻辑说明
- 外层查询先筛选出所有发生过Accept变更的
entity_id; - 通过
NOT EXISTS子查询,排除那些在当前Accept变更之后,存在从Accept到Review后续变更的实体; - 用
DISTINCT确保最终结果中每个entity_id只出现一次。
内容的提问来源于stack exchange,提问作者executable
相关产品推荐
相关产品推荐

