如何用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 取出分组后价格最高的数据的更多相关文章

  1. MySQL 对分组后的同类数据进行拼接字符串

    MySQL 对分组后的同类数据进行拼接字符串 写后台方法时遇到个问题,需要将表内同一订单号的操作记录流水进行简单拼接输出,不想取出来再操作,找了个mysql的方法直接操作 //group_concat ...

  2. postgresql分组后获取第一条数据

    -- 根据编号分组取第一条数据 select * from table t where t.no=(select max(no) from table t1 where t1.no=t.no) -- ...

  3. MySQL获取分组后的TOP 1和TOP N记录-转

    有时会碰到一些需求,查询分组后的最大值,最小值所在的整行记录或者分组后的top n行的记录,在一些别的数据库可能有窗口函数可以方面的查出来,但是MySQL没有这些函数,没有直接的方法可以查出来,可通过 ...

  4. MySQL 取分组后每组的最新记录

    修改<常用SQL之日期格式化和查询重复数据>中表test1的创建时间,修改后的测试数据如下: 以姓名分组后提取每组最新创建的记录: SELECT a.* FROM test1 AS a, ...

  5. MySQL实现分组取组内特定数据的功能

    需求:在MySQL5.7环境下,查询下面表中,各个学科前两名的学生的成绩: 1.准备数据 窗机表以及向表中插入数据 创建一张表: DROP TABLE IF EXISTS `grade`; CREAT ...

  6. 【转】Mysql相关子查询&&MySQL获取分组后的TOP N记录

    https://www.cnblogs.com/Yiran583/p/6743870.html select * from test1 a where 2 > (select count(*) ...

  7. Mysql相关子查询&&MySQL获取分组后的TOP N记录

    小燕子,哈哈哈哈~~~~~~~~~~ 相关子查询是指引用了外部查询列的子查询,即子查询会对外部查询的每行进行一次计算. 举个例子 root:test> show create table tes ...

  8. mysql,分组后,再次进行过滤

    查出平均分大于80以上的班级 select class_id, avg(score) from students group by class_id having avg(score)>80;  ...

  9. group by分组后对组内数据进行排序

    查询 每个班级英语成绩最高的前两名的记录 原文:https://www.cnblogs.com/hxfcodelife/p/10226934.html select a.Classid,a.Engli ...

  10. sqlserver 数据库分组后取第一条数据

    分享一个朋友的人工智能教程.零基础!通俗易懂!风趣幽默!大家可以看看是否对自己有帮助,点击查看教程. 比如查询用户某一天最后一笔交易后的账户余额 SELECT *( SELECT *, row_num ...

随机推荐

  1. CSS代码加滤镜将网站变为灰色(完整版)/怎么把网站变为灰色(完整版)

    CSS代码加滤镜将网站变为灰色/怎么把网站变为灰色 一.效果图 二.CSS代码 html{ background-color: rgb(238, 242, 245); background-blend ...

  2. [转载]python跨文件使用全局变量的实现

    python跨文件使用全局变量的实现 更新时间:2022-10-25 14:46:38发布时间:602天前 朗读 Python 定义了全局变量的特性,使用global 关键字修饰 1 global k ...

  3. freeRTOS移植成功

    今天来学习如何移植freeRTOS 也算是走了很多的坑,总算是把系统跑起来了 相关的教程网上也有比较详细的,本文主要说说自己踩的坑 一些汇编文件报错的问题 这个问题的原因是因为网上大部分的移植说明都是 ...

  4. Anaconda jupyter notebook 出现 kernel error 解决办法

    kenel出现错误如图: 解决办法 首先打开Anaconda Prompt输入jupyter kernelspec list查看安装的内核和位置进入安装目录,打开kernel.jason, 查看pyt ...

  5. N63050 第十二周运维作业 ansible常用模块介绍未完成

    就业和全程班本周学习内容: 二十三.Mysql数据库四 1.MySQL主从复制实现和故障排错(50分钟) 2.MySQL级联复制和主主复制架构实现(51分钟) 3.MySQL的半同步复制和复制过滤器( ...

  6. More exceptional c++读书笔记【附高清PDF下载】

    Part1我是在读完Scott Meyers的<Effective c++>之后才读到这本书的.能够讨论特定的主题而不是将一门语言作为一个整体来看待是我理解c++的首选方式,所以Sutte ...

  7. 用js实现元素两个元素位置对齐

    一.问题描述 使得填表单位那一行字与下面的表格左对齐,对表格使用css中的margin:auto实现了居中,但是对那一行字(用div包裹的)使用margin:auto不生效:并且2021年下面对应的月 ...

  8. 挂上burpsuite代理之后显示505 HTTP Version Not Supported 解决方法

    505 HTTP Version Not Supported  什么意思呢? HTTP505状态码代表的意思是 服务器不支持的HTTP版本,即 HTTP 505 HTTP Version Not Su ...

  9. calendar.getActualMaximum(calendar.DAY_OF_MONTH)的陷阱,2月份最后一天成了3月3号

    引用一下别人的链接: https://blog.csdn.net/dongyuxu342719/article/details/78131697

  10. SAR成像(四):多普勒频移的计算

    雷达系统中,雷达与目标间的相互运动会使回波信号产生频移,称为多普勒效应,对应的频移称为多普勒频率. 假设雷达发射信号为单频连续波, f ( t ) = c o s ( 2 π f 0 t + ϕ ) ...