如何筛选符合指定条件的最新行:仅获取从未达到status 0的item最新状态记录
可选优化查询方案
方案1:单遍分组查询(兼容性最高,仅需一次表扫描)
利用聚合特性直接在分组阶段完成「是否存在status=0记录」和「取最新id对应状态」的判断,无需额外子查询关联:
SELECT MAX(id) AS latest_id, item, MAX(CASE WHEN id = MAX(id) THEN status END) AS latest_status FROM updates GROUP BY item -- 仅保留从未出现过status=0的item HAVING MAX(CASE WHEN status = 0 THEN 1 ELSE 0 END) = 0;
逻辑说明:
- 分组时用
MAX(CASE WHEN status = 0 THEN 1 ELSE 0 END)判断当前item是否存在过状态为0的记录,存在则返回1,直接被HAVING条件过滤,刚好符合你场景里99%的item都会被提前过滤的特性,性能开销极低 - 仅用一次全表/索引扫描即可完成计算,没有额外关联开销
方案2:窗口函数方案(支持MySQL 8.0+/PostgreSQL/SQL Server等主流新数据库)
如果你的数据库支持窗口函数,可以用更直观的写法实现同样的单遍扫描逻辑:
WITH ranked_updates AS ( SELECT *, -- 按item分组给行倒序编号,id最大的最新记录编号为1 ROW_NUMBER() OVER (PARTITION BY item ORDER BY id DESC) AS rn, -- 标记当前item是否出现过status=0的记录 MAX(CASE WHEN status = 0 THEN 1 ELSE 0 END) OVER (PARTITION BY item) AS has_zero FROM updates ) SELECT id, item, status FROM ranked_updates WHERE rn = 1 AND has_zero = 0;
索引优化建议
给updates表建立联合索引(item, id, status),上述两个方案都可以直接走覆盖索引,无需回表查询数据,性能可以再提升数倍。
内容的提问来源于stack exchange,提问作者viraptor
相关产品推荐
相关产品推荐

