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 ...
随机推荐
- 【转载】python解决文本乱码问题及文本二进制读取后的处理
转自:https://blog.csdn.net/u011316258/article/details/50450079 python解决文本乱码问题及文本二进制读取后的处理 吲哚乙酸 当文本中含有很 ...
- Ubuntu离线安装 MySQL 5.7
来源:https://www.ngui.cc/article/show-581968.html?action=onClick 一.所需环境 操作系统:Ubuntu 20.04数据库:MySQL 5.7 ...
- 学习笔记3:Android Studio 配置NDK编译c++代码
NDK编译c++代码有两个方式: 1 ndk-build.cmd + Android.mk + Application.mk 编译, 可单独用ndk编译, 不使用IDE,使用Android需要配置b ...
- flask 项目构建
创建虚拟环境 mkvirtualenv 环境名 安装所需要的包 pip install flask == 0.12.4 pip install redis pip install flask-ses ...
- 清除Linux登录记录
CentOS cat /dev/null > /var/log/wtmp cat /dev/null > /var/log/btmp cat /dev/null > /var/log ...
- nfs-client-provisioner 利用NFS动态提供Kubernetes后端存储卷
nfs-client-provisioner 利用NFS动态提供Kubernetes后端存储卷 一.选一个节点安装nfsserver 服务 yum install nfs-common n ...
- cdn全栈加速nginx二层代理实现
1 nginx.conf中添加配置如下: server { listen 5050; location / { proxy_pass http://代理IP:3333; proxy_set_heade ...
- Qt中父子页面切换隐藏实现方法 (利用信号槽机制实现)
首先既然你打开了这篇文章,那你一定想到过,将子界面作为父界面的一个属性来实现,但是这样父界面通知子界面会很轻松,但子界面通知父界面怎么搞呢?很显然不能再子界面再实例化父界面(因为这样做会循环引用),那 ...
- 在SublimeText3中想使用快捷键调出插件ColorPicker不起作用办法解决
在SublimeText3中快速打开插件ColorPicker的快捷健是Ctrl+Shift+C,但是我试了却不管用,后来发现是跟插件ConvertToUTF8插件中的快捷键冲突导致,知道原因就好办了 ...
- Postman 测试 Web Service 和 WCF
一.postman 测试web service(1)设置url http://www.oorsprong.org/websamples.countryinfo/countryinfoservice.w ...