最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
怎样在SQL中统计每个分类下最新更新的一条完整记录?
时间:2026-06-20 09:44:46 编辑:袖梨 来源:一聚教程网
正确解法是用窗口函数ROW_NUMBER()按分类和更新时间倒序编号后取rn=1的行,或用MySQL的JOIN子查询、PostgreSQL的DISTINCT ON;过滤条件须放在子查询内以确保逻辑正确。
用窗口函数 ROW_NUMBER() 按分类和时间排序取首行
直接用 GROUP BY 加 MAX(updated_at) 只能拿到时间戳,拿不到对应那条完整记录——这是最常踩的坑。正确解法是用窗口函数给每组内的记录按更新时间倒序编号,再过滤出编号为 1 的行。
假设表叫 articles,字段有 category、title、content、updated_at:
SELECT category, title, content, updated_atFROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY category ORDER BY updated_at DESC, id DESC ) AS rn FROM articles) rankedWHERE rn = 1;
注意两点:一是 ORDER BY updated_at DESC 确保最新在前;二是追加 id DESC 防止同秒更新时结果不稳定(避免无序导致每次查询结果不一致)。
MySQL 5.7 或更老版本不支持窗口函数怎么办
得用关联子查询或自连接,但性能差、写法绕。核心思路是:对每个 category,找出它的最大 updated_at,再连回原表匹配该时间和分类。
- 用
JOIN+ 子查询(推荐,相对易读):SELECT a1.*FROM articles a1INNER JOIN ( SELECT category, MAX(updated_at) AS max_updated FROM articles GROUP BY category) a2 ON a1.category = a2.category AND a1.updated_at = a2.max_updated;
- 但要注意:如果同一分类下有多个记录
updated_at完全相同,这个写法会返回多条——不是“最新一条”,而是“最新时间的所有条”。要严格保一条,得在子查询里加id辅助去重,或改用LEFT JOIN自连接找“不存在更新时间更大的同分类记录”。
PostgreSQL 中 DISTINCT ON 是更简洁的替代方案
这是 PostgreSQL 特有语法,比窗口函数少嵌套一层,语义也更直白:
SELECT DISTINCT ON (category) category, title, content, updated_atFROM articlesORDER BY category, updated_at DESC, id DESC;
关键点:DISTINCT ON 必须配合 ORDER BY 使用,且 ORDER BY 的前导字段必须和 DISTINCT ON 一致;后续字段决定“哪一条被留下”——这里用 updated_at DESC, id DESC 确保取到最新且 ID 最大的那条。
不支持跨数据库迁移,但如果你用 PG,它比 ROW_NUMBER() 更轻量、可读性更好。
WHERE 条件不能直接写在窗口函数外层
比如想只查 status = 'published' 的最新记录,错误写法是把 WHERE status = 'published' 放在最外层——这会导致先取最新再过滤,可能漏掉某些分类(因为最新那条被过滤掉了)。
正确做法是:把过滤条件放在子查询或 CTE 内部,确保排序和编号基于已筛选的数据集:
SELECT category, title, content, updated_atFROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY category ORDER BY updated_at DESC, id DESC ) AS rn FROM articles WHERE status = 'published' -- ✅ 这里过滤) rankedWHERE rn = 1;
漏掉这一步,结果就不可靠——尤其是当某些分类最新记录恰好被 WHERE 排除时,整个分类会消失,而不是退而求其次选次新记录。
真正麻烦的不是语法,而是想清楚“最新”是针对全量数据,还是针对某个子集;这个逻辑偏差,比写错函数名还容易引发线上问题。
相关文章
- 异环棋子有何作用 06-20
- 亿万光年联合要塞如何选 06-20
- 西普大陆优雅侍鸟怎么获取 06-20
- 智能体平台开发者API接入:密钥获取与权限配置说明 06-20
- 伊莫超可狼人是哪些 06-20
- 蛋仔派对出号哪里选 06-20