如何编写PostgreSQL SQL查询:筛选无历史活动记录且仅今年参与的人员
PostgreSQL 查询仅参与今年活动且未参与过往年活动的人员
需求说明
筛选出从未参与过往年活动、仅在2022年(示例中的“今年”)参与过活动的人员。
示例数据表
tbl_evt(活动表)
| id_evt | evt_date |
|---|---|
| 1 | 2022-10-01 |
| 2 | 2022-08-05 |
| 3 | 2021-01-01 |
| 4 | 2020-06-05 |
tbl_people_evt(人员活动关联表)
| id_people | id_evt |
|---|---|
| 1 | 1 |
| 1 | 4 |
| 2 | 1 |
| 3 | 1 |
| 3 | 3 |
| 4 | 1 |
| 5 | 1 |
| 5 | 2 |
| 6 | 3 |
解决方案
这里提供两种可行的SQL写法:
方法一:使用NOT EXISTS排除过往参与者
SELECT DISTINCT pe.id_people FROM tbl_people_evt pe JOIN tbl_evt e ON pe.id_evt = e.id_evt WHERE EXTRACT(YEAR FROM e.evt_date) = 2022 AND NOT EXISTS ( SELECT 1 FROM tbl_people_evt pe_past JOIN tbl_evt e_past ON pe_past.id_evt = e_past.id_evt WHERE pe_past.id_people = pe.id_people AND EXTRACT(YEAR FROM e_past.evt_date) < 2022 );
逻辑:先筛选出2022年有活动参与记录的人员,再排除掉那些存在任何过往年份(<2022)活动记录的人。
方法二:分组后检查最小参与年份
SELECT pe.id_people FROM tbl_people_evt pe JOIN tbl_evt e ON pe.id_evt = e.id_evt GROUP BY pe.id_people HAVING MIN(EXTRACT(YEAR FROM e.evt_date)) = 2022;
逻辑:按人员分组后,检查该人员参与的所有活动中,最早的年份是2022——这意味着他没有参与过任何更早的活动。
预期查询结果
| id_people |
|---|
| 2 |
| 4 |
| 5 |
内容的提问来源于stack exchange,提问作者misterxis
相关产品推荐
相关产品推荐

