如何从数据库获取含指定内容的最新非重复articleId记录?
获取每个articleId最新记录的正确SQL写法
原查询无效的原因
你写的SELECT * FROM db where content like '%blabla%' group by articleId无法满足需求,问题出在两点:
- 多数SQL数据库(比如开启
ONLY_FULL_GROUP_BY模式的MySQL)不允许SELECT *搭配GROUP BY——未被聚合的列没有明确的取值逻辑,数据库无法确定返回分组里的哪条数据。 - 就算数据库允许这种写法,它也只会返回每个
articleId分组的第一条记录,而非modifiedDate最新的那条,完全不符合你的要求。
可行解决方案
方案1:子查询关联(兼容所有SQL数据库)
先筛选出每个符合条件的articleId对应的最新修改日期,再关联原表拿到完整记录:
SELECT t.* FROM db t INNER JOIN ( SELECT articleId, MAX(modifiedDate) AS latest_modified FROM db WHERE content LIKE '%blabla%' GROUP BY articleId ) t2 ON t.articleId = t2.articleId AND t.modifiedDate = t2.latest_modified WHERE t.content LIKE '%blabla%'
方案2:窗口函数(适用于MySQL 8.0+、PostgreSQL、SQL Server等)
用ROW_NUMBER()窗口函数按articleId分组,按modifiedDate降序排序,直接取每组的第一条:
SELECT id, articleId, createDate, modifiedDate, content FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY articleId ORDER BY modifiedDate DESC) AS rn FROM db WHERE content LIKE '%blabla%' ) t WHERE rn = 1
如果同一个articleId存在多条modifiedDate相同的最新记录,想全部保留的话,把ROW_NUMBER()换成RANK()即可。
方案3:简化聚合写法(仅当modifiedDate唯一时可用)
如果每个articleId的modifiedDate不会重复,也可以用这种更简洁的写法:
SELECT id, articleId, createDate, MAX(modifiedDate) AS modifiedDate, content FROM db WHERE content LIKE '%blabla%' GROUP BY articleId, id, createDate, content
不过这种写法依赖数据库对非聚合列的处理规则,通用性不如前两种。
内容的提问来源于stack exchange,提问作者kontorrr testor
相关产品推荐
相关产品推荐

