0
点赞
收藏
分享

微信扫一扫

测一测自己的Sql能力之MYSQL的GROUPBY你弄懂了吗?


🎈个人公众号:🎈 :✨✨ 可为编程 ✨✨ 🍟🍟
🔑个人信条:🔑 知足知不足 有为有不为 为与不为皆为可为🌵
🍉本篇简介:🍉 本片详细说明了MYSQL的GROUPBY使用规则和注意要点,并给出具体操作实例,如有出入还望指正。

场景描述如下:

订单表
(包含字段有:订单ID[自增]、客户ID、下单时间、订单金额、商品名称)
采用一个SQL语句,查询出:
每一位客户最后一次的下单时间、订单金额、商品名称;以及每一位客户的累计订单总笔数、最大订单金额

看起来很简单哈,有的同学就会这样去写了,如下:

SELECT
	MAX( good_price ) AS max_good_price,
	COUNT( DISTINCT order_id, order_id ) AS sum_order_num,
	order_person_id,
	MAX( create_time ) AS create_time,
	good_price,
	order_name AS good_name 
FROM
	`t_order_info` 
GROUP BY
	order_person_id

在数据很少的时候,通过这种就很容易实现了,并且每一个用户当时只有一条对应的信息,也就是order_person_id所对应的商品信息只有互不相同的一条信息。

很显然这样是不合理的,当出现多条数据的时候就会产生对应的一个错误,那就是会取到其他的数据,显示的order_person_id为3,但却不是3的其他数据字段。所以当我们去查询的时候 发现数值不对。

测一测自己的Sql能力之MYSQL的GROUPBY你弄懂了吗?_mysql

SELECT * FROM  `t_order_info` WHERE order_person_id = 5 ORDER BY create_time DESC;

测一测自己的Sql能力之MYSQL的GROUPBY你弄懂了吗?_sql_02


然后继续查看是那种原因呢?

对比两次GROUPBY查询:

SELECT
		toi.* 
	FROM
		( SELECT order_person_id, max( create_time ) time FROM t_order_info GROUP BY order_person_id ) tmp
		INNER JOIN t_order_info toi ON tmp.order_person_id = toi.order_person_id 
		AND tmp.time = toi.create_time 
ORDER BY order_person_id DESC

根据order_person_id进行排序查询,结果如下:
1723	小卡车	3	3
1724	小卡车	4	4
1572	小卡车-AB	5	5
1708	小卡车	6	6
1717	小卡车	6	6
1709	小卡车	7	7
1718	小卡车	7	7
1710	小卡车	8	8
1719	小卡车	8	8
1702	小卡车	9	9
1711	小卡车	9	9
1720	小卡车	9	9
1703	小卡车	10	10
1712	小卡车	10	10
1721	小卡车	10	10
1722	小卡车	11	11



SELECT
		toi.* 
	FROM
		( SELECT order_person_id, max( create_time ) time FROM t_order_info GROUP BY order_person_id ) tmp
		INNER JOIN t_order_info toi ON tmp.order_person_id = toi.order_person_id 
		AND tmp.time = toi.create_time 

默认GROUPBY 分组ID排序
1572	小卡车-AB	5	5	7
1702	小卡车	9	9	7
1703	小卡车	10	10	7
1708	小卡车	6	6	7
1709	小卡车	7	7	7
1710	小卡车	8	8	7
1711	小卡车	9	9	7
1712	小卡车	10	10	7
1717	小卡车	6	6	7
1718	小卡车	7	7	7
1719	小卡车	8	8	7
1720	小卡车	9	9	7
1721	小卡车	10	10	7
1722	小卡车	11	11	7
1723	小卡车	3	3	7
1724	小卡车	4	4	7

正式的SQL例子,采用INNERJOIN:

第二步进行聚合函数的操作:

SELECT
	MAX( good_price ) AS max_good_price,
	COUNT( order_id ) AS sum_order_num,
	MAX( create_time ) AS max_create_time,
	order_person_id
FROM
	`t_order_info` 
GROUP BY
	order_person_id;

最终版本:

最终版:
SELECT
	MAX( toi1.good_price ) AS max_good_price,
	COUNT( toi1.order_id ) AS sum_order_num,
	toi1.order_person_id,
	max_create_time, 
	b.good_price,
	b.order_name,
	b.order_person_id
FROM
	`t_order_info`AS toi1 INNER JOIN (
	SELECT
max(create_time) AS max_create_time, good_price,order_name,order_person_id
FROM
	(
	SELECT
		toi.* 
	FROM
		( SELECT order_person_id, max( create_time ) time FROM t_order_info GROUP BY order_person_id ) tmp
		INNER JOIN t_order_info toi ON tmp.order_person_id = toi.order_person_id 
		AND tmp.time = toi.create_time 
		
	) AS a 
GROUP BY  
	order_person_id
	) AS b ON toi1.order_person_id = b.order_person_id
	
	GROUP BY
	b.order_person_id

测一测自己的Sql能力之MYSQL的GROUPBY你弄懂了吗?_分组_03

SELECT * FROM (
SELECT
		order_id,
		order_person_id,
		good_price,
		order_name AS good_name,
		create_time 
	FROM
		`t_order_info` 
	WHERE create_time = (
		SELECT
		MAX( create_time )) 
	GROUP BY
		order_person_id,
		(SELECT MAX( create_time )) 
	ORDER BY
		create_time DESC 		
) AS a GROUP BY
		order_person_id

最终版本:

最终版:
SELECT
	MAX( toi.good_price ) AS max_good_price,
	COUNT( toi.order_id ) AS sum_order_num,
	MAX( toi.create_time ) AS max_create_time,
	toii.good_price,
	toii.good_name,
	toii.order_person_id 
FROM
	`t_order_info` AS toi
	INNER JOIN (
	SELECT
		* 
	FROM
		( SELECT order_person_id, good_price, order_name AS good_name, create_time FROM `t_order_info` GROUP BY order_person_id, ( SELECT MAX( create_time )) ORDER BY create_time DESC ) AS a 
	GROUP BY
		order_person_id 
	) AS toii ON toi.order_person_id = toii.order_person_id 
GROUP BY
	toii.order_person_id

以下是其他排查语句,也先列在这里。

SELECT max(create_time), order_person_id FROM t_order_info GROUP BY order_person_id;

SELECT max(create_time), good_price,order_name,order_person_id FROM t_order_info GROUP BY order_person_id;

同时这里面里一个终极版本的写法:

select 
  temp.order_person_id  客户ID,
  max(temp.create_time) 最后一次的下单时间,
  temp.good_price  最后一次的下单金额,
  temp.order_name  最后一次的下单商品,
  count(*)  客户的累计订单总笔数,
  max(good_price)  最大订单金额
from (select * from t_order_info order by create_time desc, order_id desc limit 9999999999) as temp
group by temp.order_person_id;

这是我的直属领导给我写的语句,多么的简短,美丽大方,留做纪念。

欢迎感兴趣的小伙伴一起探讨学习知识,以上是个人的一些总结分享,如有错误的地方望各位留言指出,十分感谢。觉得有用的话别忘点赞、收藏、关注,手留余香! 😗 😗 😗


欢迎大家关注【可为编程】,成长,进步,编程,技术、掌握更多知识!

测一测自己的Sql能力之MYSQL的GROUPBY你弄懂了吗?_后端_04


举报

相关推荐

0 条评论