概述
前言
假设有一个存储文章信息的数据表(article),结构如下:
字段名 | 说明 |
---|---|
id | 主键ID |
author_id | 作者ID |
title | 文章标题 |
content | 文章内容 |
add_time | 文章添加时间 |
edit_time | 文章上一次编辑时间 |
作者和文章是一对多的关系,现在需要从这个表里查出每个作者最近编辑过的一篇文章,那么可以怎么写SQL语句呢?
分析
这个查询有两个条件:
- 每个作者仅需展示一篇文章
- 展示的文章是最新编辑过的那一篇
针对第一个条件,可以使用GROUP BY
来实现,但第二个条件就有点棘手了,因为MySQL在分组的时候,具体留下哪一条数据是无法指定的,网上有一些方法是用INNER JOIN
来处理,示例:
SELECT a.* FROM article a
INNER JOIN (SELECT MAX(edit_time) FROM article GROUP BY author_id) AS b
ON b.edit_time = a.edit_time
不用JOIN
的另一种写法:
SELECT * FROM article WHERE edit_time IN (
SELECT MAX(edit_time) FROM article GROUP BY author_id
)
如果edit_time
字段跟文章是一对一关系的话,这种方法是可行的,但在我们这个场景里,明显不是一对一关系,因此这种方法不能使用。
解决方法
方案一:
既然GROUP BY
无法指定留下哪一条数据,那么就干脆不用GROUP BY
,用子查询来处理就好,语句如下:
SELECT * FROM article a
WHERE id = (SELECT id FROM article WHERE author_id=a.author_id ORDER BY edit_time DESC LIMIT 1)
使用EXPLAIN
分析这语句的执行计划,会发现使用到独立子查询(DEPENDENT SUBQUERY),表数据量大的时候会有性能问题,因此不能用在线上业务,平时导数据偶尔使用一下还是没问题的。
方案二:
如果MySQL版本是8.0以上的话,可以使用窗口函数:
SELECT t.* FROM (
SELECT *,ROW_NUMBER() OVER(PARTITION BY author_id ORDER BY edit_time DESC) AS rank FROM article
) AS t WHERE t.rank <= 1
最后
以上就是外向鸵鸟为你收集整理的MySQL使用GROUP BY分组时如何留下指定的行的全部内容,希望文章能够帮你解决MySQL使用GROUP BY分组时如何留下指定的行所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复