SQL结合COUNT与TOP查询高ID前3条记录关闭数的问题
问题说明
现有all_records记录表,包含recordID、status两个字段,status取值为open/closed,样例数据如下:
| recordID | status |
|---|---|
| 1 | Closed |
| 2 | Closed |
| 3 | Closed |
| 4 | Closed |
| 5 | Open |
需求为查询recordID最大的3条记录中,状态为Closed的记录总数。以上述样例为例,ID最高的3条记录为ID=3、4、5,其中Closed状态共2条,即预期返回结果为2。
原有错误SQL执行后返回结果为4,不符合预期,原代码如下:
select recordid, (select top 3 count(recordid) from all_records where status = 'Closed') as CNT from all_records
错误原因
- 子查询逻辑顺序写反:子查询先通过
WHERE status = 'Closed'过滤了全表所有关闭状态的记录,再执行COUNT聚合。由于COUNT()聚合后只会返回1行结果,写在COUNT前的TOP 3完全不生效,最终统计的是全表所有Closed状态的记录总数,也就是样例中的4,和需求逻辑完全不符。 - 外层查询无意义遍历全表
recordid,会返回和表数据行数一致的结果集,每一行的CNT值都是错误的4。
正确实现
核心逻辑是先按recordID倒序取出ID最高的3条记录,再在这3条记录中统计Closed状态的数量。
SQL Server / Access 支持TOP语法的写法:
SELECT COUNT(*) AS CNT FROM ( SELECT TOP 3 status FROM all_records ORDER BY recordID DESC ) AS top_3_records WHERE status = 'Closed'
MySQL / PostgreSQL 等支持LIMIT语法的写法:
SELECT COUNT(*) AS CNT FROM ( SELECT status FROM all_records ORDER BY recordID DESC LIMIT 3 ) AS top_3_records WHERE status = 'Closed'
内容的提问来源于stack exchange,提问作者notalent26
相关产品推荐
相关产品推荐

