mysql 取出分组后价格最高的数据
如何用mysql 取出分组后价格最高的数据 ?
看到这个问题,就想到了用 max 函数和 group by 函数,先 group by 然后取得 max, 但是这样真的可以吗? 不可以 !
为什么? 因为要了解 :group by 后,select 取出的默认只是每个分组的第一条数据,但是这条数据和选出的 max,很有可能并不是同一条中的。
比如我们表的内容是这样的:

尝试一(失败)
执行sql语句 select * from test_group group by num; 得到的结果:

执行sql语句 select * , max(price) from test_group group by num; 得到的结果:

发现 max price 的价格和当前这条数据的实际价格根本对应不起来。由此可见: 这种写法其实是错误的,取出来的数据没有任何含义
尝试二(失败)
在网上看到这样一种写法:既然分组就取第一条数据,那我们先把表排序,再从排序的表中去分组取第一条数据
select * from test_group order by price desc;

再从这个表中去分组取得第一条数据:select * from (select * from test_group order by price desc) as s group by s.num;

经过实际试验后,发现结果并不对,看一位博主介绍说,mysql 5.7之后对于这个顺序好像进行改变了,所以使用这个语句要特别小心mysql版本。
尝试三(失败)
另外还有一种写法是:先取得每个num下最大的price, 再根据得到的price去找对应的数据
select max(price) from test_group group by num;

select * from test_group where price in (select max(price) from test_group group by num);

看起来可以了,是取出的每组下面最大的数据,但是如果遇到下面这种情况就会有问题啦!
我们加了八八这条数据,属于 12 组下 价格为130的数据,这样最终的结果 四四 和 八八都被筛选出来了 !!因为我们筛选出来的max(price) 有130,而八八的价格恰好是130。


优化尝试三(成功)
可以优化下上面这条sql:我们选择max(price)时还把对应的组也筛选出来,去判断两个的num也是相同的,这就需要做一个表的连接
首先得到num及num下的最高价格:select num, max(price) as max_price from test_group group by num;

将上面的子表与原表进行连接,条件是num和price都要相同,得到结果如下:
select * from test_group as s1 left join (select num, max(price) as max_price from test_group group by num) as s2 on s1.num=s2.num and s1.price=s2.max_price;


然后我们筛选出s2.num 不为空的数据即可
select s1.id as id, s1.num as num, s1.price as price, s1.name as name from test_group as s1 left join (select num, max(price) as max_price from test_group group by num) as s2 on s1.num=s2.num and s1.price=s2.max_price where s2.num is not null;

尝试四(成功)
我们将表自连接,连接条件是:1的价格<2的价格并且部门相同,这样的话那些价格最高的不会有数据和它连接,最后筛选2中id is null 的数据就可以了
先将表自连接:select * from test_group s1 left join test_group s2 on s1.price < s2.price and s1.num=s2.num;

筛选 s2.id is null 的数据:
select s1.id as id, s1.num as num, s1.price as price, s1.name as name from test_group s1 left join test_group s2 on s1.price < s2.price and s1.num=s2.num where s2.id is null;

这样得到的结果和上面也一样
尝试五(未经过测试)
使用partition by函数来实现,但是这个函数只在mysql 8版本上运行,我的是5.7,太低了,运行不起来,没有经过验证。 这个函数也可以用在hive表中
over(partition by num order by price desc) : 这个语句的意思是先按照 num 进行分组,组内再按照price进行排序
row_number()over(partition by cno order by degree desc) mm: 这个语句的意思是对于上面的结果每组内进行编号,且这列编号列名为 mm
SELECT *
FROM (select sno,cno,degree,
row_number()over(partition by cno order by degree desc) mm
from score)
where mm = 1;

mysql 取出分组后价格最高的数据的更多相关文章
- MySQL 对分组后的同类数据进行拼接字符串
MySQL 对分组后的同类数据进行拼接字符串 写后台方法时遇到个问题,需要将表内同一订单号的操作记录流水进行简单拼接输出,不想取出来再操作,找了个mysql的方法直接操作 //group_concat ...
- postgresql分组后获取第一条数据
-- 根据编号分组取第一条数据 select * from table t where t.no=(select max(no) from table t1 where t1.no=t.no) -- ...
- MySQL获取分组后的TOP 1和TOP N记录-转
有时会碰到一些需求,查询分组后的最大值,最小值所在的整行记录或者分组后的top n行的记录,在一些别的数据库可能有窗口函数可以方面的查出来,但是MySQL没有这些函数,没有直接的方法可以查出来,可通过 ...
- MySQL 取分组后每组的最新记录
修改<常用SQL之日期格式化和查询重复数据>中表test1的创建时间,修改后的测试数据如下: 以姓名分组后提取每组最新创建的记录: SELECT a.* FROM test1 AS a, ...
- MySQL实现分组取组内特定数据的功能
需求:在MySQL5.7环境下,查询下面表中,各个学科前两名的学生的成绩: 1.准备数据 窗机表以及向表中插入数据 创建一张表: DROP TABLE IF EXISTS `grade`; CREAT ...
- 【转】Mysql相关子查询&&MySQL获取分组后的TOP N记录
https://www.cnblogs.com/Yiran583/p/6743870.html select * from test1 a where 2 > (select count(*) ...
- Mysql相关子查询&&MySQL获取分组后的TOP N记录
小燕子,哈哈哈哈~~~~~~~~~~ 相关子查询是指引用了外部查询列的子查询,即子查询会对外部查询的每行进行一次计算. 举个例子 root:test> show create table tes ...
- mysql,分组后,再次进行过滤
查出平均分大于80以上的班级 select class_id, avg(score) from students group by class_id having avg(score)>80; ...
- group by分组后对组内数据进行排序
查询 每个班级英语成绩最高的前两名的记录 原文:https://www.cnblogs.com/hxfcodelife/p/10226934.html select a.Classid,a.Engli ...
- sqlserver 数据库分组后取第一条数据
分享一个朋友的人工智能教程.零基础!通俗易懂!风趣幽默!大家可以看看是否对自己有帮助,点击查看教程. 比如查询用户某一天最后一笔交易后的账户余额 SELECT *( SELECT *, row_num ...
随机推荐
- js提交数据
一.from表单提交 <form action="" method="post" enctype="multipart/form-data&qu ...
- Vulnhub:vulnuni1.0.1靶机
kali:192.168.111.111 靶机:192.168.111.192 信息收集 端口扫描 nmap -A -v -sV -T5 -p- --script=http-enum 192.168. ...
- Linux驱动、应用调试技巧
原文地址:https://hceng.cn/2019/04/08/Linux%E9%A9%B1%E5%8A%A8%E3%80%81%E5%BA%94%E7%94%A8%E8%B0%83%E8%AF%9 ...
- virtualenvwrapper使用命令
virtualenvwrapper使用命令 创建虚拟环境:mkvirtualenv + test1 查看虚拟环境:lsvirtuslenv 删除虚拟环境:rmvirtualenv + test1 退出 ...
- UISelector
1.UiSelector的基本方法 UiSelector对象可以理解为一种条件对象,描述的是一种条件,可以配合UiObject使用得到某个符合条件的控件对象. 所有的方法都是public的,且都返回U ...
- vue 清空element表单数据
resetFields是用于针对整个表单的 Form Methods(整个表单) resetField 是针对表单项的 Form-Item Methods(表单的某一个项) this.$refs['e ...
- CentOS Linux release 7.6 zabbix5.0 安装
# zabbix 安装关方文档 https://www.zabbix.com/cn/download?zabbix=5.0&os_distribution=centos&os_vers ...
- PCB走线宽度与电流、温度的关系
测试PCB的线长为24cm 其他:
- bat 脚本用 winrar 自动打包压缩文件
bat 的文本如下: --声明winrar软件的位置set Path=;"C:\Program Files\WinRAR";%SystemRoot%\system32--用forf ...
- 关于ie浏览器query ajax提交单个操作无效
第一次写博客 大家不要喷我!!!! 需求需要开发一个无刷新的用户注销和恢复注销功能 遇到的实际问题直接贴图----> 这是开始页面 当点击红xx时提示修改成功 这里似乎是对的哈 但是等点击刷新的 ...