GROUP BY获得各组中时间最大的记录集 - 辟谣亲测版

总有那些个需求,想要group by分组数据,但又想规定获取其中某个条件最大/最小的数据。本人也遇到这么个需求,于是上网搜了搜,发现大多都是这样的一个答案:先将要分组的数据按照条件进行排序,之后获取其数据集来进行分组。这种方法很常见,但是广大网友的眼睛是雪亮的:这种方式是不行的!

本人也是看到这篇文章有感而发:group by分组后获得每组中时间最大的那条记录

接下来让我们来试试看,这种方式到底是不是真的不可取

首先,假设有这样一个订单表(假设的,真的就是拿来随便测试的)

CREATE TABLE `order_test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(11) unsigned NOT NULL COMMENT '下单用户id',
  `pay_money` int(11) NOT NULL DEFAULT '0' COMMENT '支付金额(单位为分)',
  `pay_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '支付时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

再来捏造这样几条数据:

id user_id pay_money pay_time
1 1 1000 2020-06-01 00:00:00
2 1 2000 2020-06-02 00:00:00
3 1 3000 2020-06-03 00:00:00
4 2 1500 2020-06-01 00:00:00
5 2 2500 2020-06-02 00:00:00
6 2 3500 2020-06-03 00:00:00
7 3 1250 2020-06-01 00:00:00
8 3 2250 2020-06-02 00:00:00
9 3 3250 2020-06-03 00:00:00

接下来按照网上流传方法来试试看,获取各个用户最新支付的订单:

  1. 先对用户id进行正序排序,再对支付时间进行倒序排序
  2. 将第1步查询的数据集当做临时表,已经被排好序了
  3. 对临时表进行group by分组,得到最终结果
SELECT
	* 
FROM
	( SELECT * FROM `order_test` ORDER BY user_id ASC, pay_time DESC ) A 
GROUP BY
	user_id

在这里插入图片描述

可以明显的看到,结果中支付时间都是最旧的,根本不是我们想要的结果!


那么怎样才能拿到我们真正想要的结果呢?

强大的网友提供了这样一个方法:在刚才那条SQL上加一个HAVING 1就可以了

什么操作?这么神奇的?来来试试

SELECT
	* 
FROM
	( SELECT * FROM `order_test` HAVING 1 ORDER BY user_id ASC, pay_time DESC ) A 
GROUP BY
	user_id

在这里插入图片描述

ps:user_id ASC是可以不用写的

膜拜大佬!!!

虽然不懂原理但是真的成功了,实测可用!大佬牛批!(大佬就在本文参考文章的评论中,有需要的同学可以去膜拜膜拜,有考必过)


当然,不只是支付时间可以用这种方式,其他字段也是可以使用的

比如:获取各个用户支付金额最多的一条订单

SELECT
	* 
FROM
	( SELECT * FROM `order_test` HAVING 1 ORDER BY pay_money DESC ) A 
GROUP BY
	user_id

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_38125045/article/details/107466166
今日推荐