如何查询PostgreSQL中无2022年1月1日后记录的ID数量
统计无2022年1月1日后记录的ID数量(PostgreSQL)
我有一个包含ID和EventDate列的PostgreSQL数据表,记录日期范围从1960年1月1日到当前日期。需要统计没有2022年1月1日后事件记录的ID数量。
我的思路是先找出存在2022年1月1日后记录的ID,再排除这些ID得到目标结果,但不确定如何在同表同字段中实现排除操作。我已写出查询有该日期后记录的ID的SQL:
SELECT id, eventdate FROM table WHERE eventdate >= '01/01/2022'
尝试用NOT查询得到的是该日期前的记录,但这些ID可能同时存在日期后的记录:
SELECT id, eventdate FROM table WHERE ( not ( eventdate >= '01/01/2022' ) or eventdate is null)
请问应如何构造SQL来排除有指定日期后记录的ID,得到无该日期后记录的ID?该SQL将用于Excel VBA连接PostgreSQL的场景。
示例表如下:
ID | eventdate 1 | 28/12/2023 2 | 27/08/2024 3 | 12/05/2022
解决方案
方法一:NOT EXISTS子查询(推荐,性能较好)
SELECT COUNT(DISTINCT id) AS no_post_2022_count FROM your_table t1 WHERE NOT EXISTS ( SELECT 1 FROM your_table t2 WHERE t2.id = t1.id AND t2.eventdate >= '2022-01-01' );
- 逻辑:检查每个ID,只要不存在任何一条2022年1月1日之后的记录,就纳入统计
COUNT(DISTINCT id)确保每个ID只被计数一次,避免重复- 注意:PostgreSQL推荐使用
'YYYY-MM-DD'格式的日期字符串,避免因地区设置导致的解析错误
方法二:GROUP BY + HAVING子句
SELECT COUNT(id) AS no_post_2022_count FROM ( SELECT id FROM your_table GROUP BY id HAVING MAX(eventdate) < '2022-01-01' OR MAX(eventdate) IS NULL ) AS subquery;
- 逻辑:按ID分组后,取每个ID的最晚记录日期;如果最晚日期早于2022年1月1日,或所有记录的eventdate都是NULL,说明该ID无2022年后的记录
- 子查询筛选符合条件的ID,外层统计数量
方法三:EXCEPT集合操作
SELECT COUNT(DISTINCT id) AS no_post_2022_count FROM ( SELECT id FROM your_table EXCEPT SELECT id FROM your_table WHERE eventdate >= '2022-01-01' ) AS subquery;
- 逻辑:先获取所有ID,再排除有2022年后记录的ID,剩余的就是目标ID,最后统计数量
注意事项
- 将
your_table替换为你的实际表名 - 如果需要获取具体的ID列表而非数量,将外层查询的
COUNT(DISTINCT id)改为id即可 - 日期格式优先使用
'2022-01-01',避免歧义
内容的提问来源于stack exchange,提问作者BradleyS
相关产品推荐
相关产品推荐

