测一测自己的Sql能力之MYSQL的GROUPBY你弄懂了吗?
场景描述如下:
订单表
(包含字段有:订单ID[自增]、客户ID、下单时间、订单金额、商品名称),
采用一个SQL语句,查询出:
每一位客户最后一次的下单时间、订单金额、商品名称;以及每一位客户的累计订单总笔数、最大订单金额
看起来很简单哈,有的同学就会这样去写了,如下:
SELECTMAX( 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 BYorder_person_id
在数据很少的时候,通过这种就很容易实现了,并且每一个用户当时只有一条对应的信息,也就是order_person_id所对应的商品信息只有互不相同的一条信息。
很显然这样是不合理的,当出现多条数据的时候就会产生对应的一个错误,那就是会取到其他的数据,显示的order_person_id为3,但却不是3的其他数据字段。所以当我们去查询的时候 发现数值不对。
SELECT * FROM `t_order_info` WHERE order_person_id = 5 ORDER BY create_time DESC;
然后继续查看是那种原因呢?
首先我们一定要明白,GROUPBY是每次只取表格的第一条数据,比如按照order_person_id进行分类,这样就会每次遇到相同的order_person_id时候,就会取第一个职,这样就出现了上面所展示的结果。
所以首先我们可以先查出来每个下单人所对应的最新下单时间以及下单人order_person_id编号,这样我们在拿着这组编号再去联查原始表INNER JOIN,将我们的时间最大值和其他相关字段查出来,同时要按照下单人ID进行分组,这样查出来的数据存在重复的订单数据,所以我们再嵌套一层GROUPBY order_person_id,这样就会按照含有重复数据集合中的默认id顺序进行分组并从该顺序中逐一取order_person_id的第一个值,然后生成新得集合。
对比两次GROUPBY查询:
SELECTtoi.* FROM( SELECT order_person_id, max( create_time ) time FROM t_order_info GROUP BY order_person_id ) tmpINNER 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 11SELECTtoi.* FROM( SELECT order_person_id, max( create_time ) time FROM t_order_info GROUP BY order_person_id ) tmpINNER 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 *
FROM (SELECT toi.*FROM (SELECT order_person_id,max(create_time) TIMEFROM t_order_infoGROUP BY order_person_id) tmpINNER JOIN t_order_info toi ON tmp.order_person_id = toi.order_person_idAND tmp.TIME = toi.create_time) AS a
GROUP BY order_person_id;
-- GROUP BY 默认取第一个
第二步进行聚合函数的操作:
SELECTMAX( 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 BYorder_person_id;
最终版本:
最终版:
SELECTMAX( 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(SELECTtoi.* FROM( SELECT order_person_id, max( create_time ) time FROM t_order_info GROUP BY order_person_id ) tmpINNER 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_idGROUP BYb.order_person_id
还可以根据最新的时间进行分组,不采用INNERJOIN的形式。
SELECT * FROM (
SELECTorder_id,order_person_id,good_price,order_name AS good_name,create_time FROM`t_order_info` WHERE create_time = (SELECTMAX( create_time )) GROUP BYorder_person_id,(SELECT MAX( create_time )) ORDER BYcreate_time DESC
) AS a GROUP BYorder_person_id
最终版本:
最终版:
SELECTMAX( 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 toiINNER 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 BYorder_person_id ) AS toii ON toi.order_person_id = toii.order_person_id
GROUP BYtoii.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你弄懂了吗?相关推荐
- 报志愿时计算机一大类分数,高考出分在即 测一测你的分数可以上哪些大学?...
2020年高考出分在即,志愿填报成为此时的头等大事.只有成功的完成了高考志愿填报,如愿被心仪的大学和专业录取才算是大功告成. 每一年,都有高分考生,因为志愿填报的失误,从而错失理想大学.也都有低分考生 ...
- 运气指数测试软件,测一测最近的运势如何,有什么测试运势的软件
说到测一测最近的运势如何,大家都了解,有人问求测算运程,最近不太顺利,另外,还有人想问最近运势不太好,帮帮测里的大师能化解吗,这是怎么回事?其实有好家伙测试运势的软件吗?门阀推举分秒!,下面就一起来看 ...
- 测一测你的blog魔症有多严重
测一测你的blog魔症有多严重 在Donews.net那里看到了这个有趣的测试:Are You a Blogaholic? 用来测试你对Blog的迷恋程度. 下面是我的得分与评价: 14058 peo ...
- mc有什么红石机器人_我的世界:mc玩家与非mc玩家眼中的世界,测一测你mc中毒有多深...
阅读本文前,请您先点击上面的"蓝色字体",再点击"关注",这样您就可以继续免费收到文章了.每天都有分享,完全是免费订阅,请放心关注. 注:本文转载自网络,不代表 ...
- 软件开发测试男友花束,观察这四束花束凭直觉选一束花?测一测别人都在羡慕你的什么?...
观察这四束花束凭直觉选一束花?测一测别人都在羡慕你的什么? 每个人都会有羡慕别人的地方,毕竟有些东西是你怎么努力都达不到,但是别人轻易就能达到的,比如说一些人天生家里条件就很好,所以都不需要怎么努力就 ...
- 520|测一测你和ta的夫妻相
(本内容转载自公众号"科技与Python") 相处时间越久的夫妻,往往会越像彼此.那么事实真的是这样吗. 今天这个特殊的日子里,小编熬夜为大家奉上这个测一测你和哪个明星最有夫妻相 ...
- 淘宝客推广的优势 推广作用提高销量、转化率、测图测款
今天个大家介绍一种推广方式淘宝客推广,推广方式越来越多,例如直通车.钻展. v兔等,淘宝客是钻展中的一种推广方式,但是在那么多推广方式下为什么淘宝客这种方式能存活下来,并且使用它的人还那么多.我们将从 ...
- 淘宝爆款打造——测款测图,如何打造爆款,淘宝X模型
一.重点 想要打造爆款,首先最重要的就是这个产品本身有成为爆款的潜质,丑小鸭之所以能成为白天鹅,那是因为他本身就是白天鹅.所以我们在打造爆款之前最重要的是先进行测款测图,确认宝贝有潜力后再进行后续操作 ...
- 四小时测试你的Sql能力--- MySQL经典练习50题
1 简介 Sql能力是开发人员的业务能力之根,平常习惯了CRUD,可不要忘了回归根本哦! 2 初始环境 2.1 表结构 –1.学生表 Student(s_id,s_name,s_birth,s_sex ...
最新文章
- Windows环境 安装dlib cv2(python) 总结
- 【转】【VC】VC程序运行时间测试函数
- yum下载包保存到本地
- 砝码问题之一(回头发现貌似多重背包)
- 一次诡异的数据库死锁问题排查过程 1
- Java对象内存结构
- mysql题目_MySQL练习题
- trie树 mysql_Trie树详解(转)
- 好奇心和目标:科学力量的源泉 | Cell编辑部社论
- 《Python学习手册》——使用入门
- VC 控件的字体控制 若将字体设置成“宋体、仿宋—GB2312、隶书、幼圆”中的某一字体时,需将lfCharSet设置成GB2312—CHARSET才使设置的字体有效...
- python爬虫02 - 爬虫请求模块 request库 json数据
- 利用jink的驱动软件j-flash 合并两个hex的方法,bootloader+app
- Datawhale- DS- Jun - 第一章:第一节数据载入及初步观察-课程
- C fork introduce
- JavaScript 正则匹配中英文姓名
- 我的MATLAB学习之路
- 石油基琥珀酸的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- 读《MySQL性能调优与架构设计》笔记之ORDER BY,GROUP BY 和DI STI NCT 优化
- top期刊,顶级期刊,顶级期刊,jcr分区和中科院分区
热门文章
- 获得“网管师”资格证书,开启新的网管职业生涯
- [数据库_2]-Windows 桌面数据库 Access 简明教程
- InnoSetup程序开机自启
- 011 索引的优点,特大型的表考虑分区技术
- 【DS实践 | Coursera】Assignment 3 | Applied Plotting, Charting Data Representation in Python
- 中国机器博弈事业开拓者、CAAI 会士徐心和教授因病逝世...
- 使用git工具提交上传代码到GitHub上或者远程仓库
- 魅族mx1Android4.4,魅族MX如何升级安卓4.0
- Discuz! version 5.0.0 suffers from a cross site sc
- 安徽农村信用社网银转账显示服务器无响应,农村信用社企业网银转账显示状态无效是怎么回事...