关于问题

如何查询组内最大的,最小的,大家或许都知道,无非是min、max的函数使用。可是如何在MySQL中查找组内最好的前两个,或者前三个?

什么是相关子查询

在提出对于这个问题的对应方法之前,首先来理解一个概念:相关子查询。

所谓相关子查询,就是其查询的执行依赖于外部查询。多数情况下是子查询的where子句中引用了外部查询的表。执行过程:
  • 从外层查询中取出一个元组,将元组相关列的值传给内层查询
  • 执行内层查询,得到子查询操作的值
  • 外查询根据子查询返回的结果或结果集得到满足条件的行
  • 然后外层查询取出下一个元组重复做步骤1-3,直到外层的元组全部处理完毕。

下面会结合例子,在说明组内取值的同时,是如何使用相关子查询的。

在MySQL中查询每组中的前N个值

有如上的表,我们需要找出每个类型(type)中最便宜的前两种水果,我们可以采取这样的方法:
select type, variety, price
from fruits
where (
select count(*) from fruits as f
where f.type = fruits.type and f.price < fruits.price
) <= 1;
6
 
1
select type, variety, price 
2
from fruits
3
where (
4
   select count(*) from fruits as f
5
   where f.type = fruits.type and f.price < fruits.price
6
) <= 1;

这个查询语句就使用到了相关子查询,结合之前我们提到的相关子查询的查询步骤,我们来解析一下这个SQL语句。

从表中首先取出第一条数据,type为apple,variety为gala,price为2.79。相关子查询中,会将元组相关列的值传给内层查询,在子查询中我们看到
select count(*) from fruits as f
where f.type = fruits.type and f.price < fruits.price
2
 
1
select count(*) from fruits as f
2
where f.type = fruits.type and f.price < fruits.price

也就是说,实际上这条语句此时应该是这样
select count(*) from fruits as f
where f.type = apple and f.price < 2.79
2
 
1
select count(*) from fruits as f
2
where f.type = apple and f.price < 2.79
即,在apple这个类别中,价格比2.79还要低的元组的数量。

我们再看全貌
select type, variety, price
from fruits
where (
select count(*) from fruits as f
where f.type = apple and f.price < 2.79
) <= 1;
6
 
1
select type, variety, price
2
from fruits
3
where (
4
   select count(*) from fruits as f
5
   where f.type = apple and f.price < 2.79
6
) <= 1;
可以知道,apple中价格低于2.79的只有fuji这个元组,即值为1,满足子条件<=1的条件,所以该元组会被输出。

如果不好理解,这样来看。其实这个子条件的意思就是在说,我提取一个元组A,如果这个元组A所属的类别中,价格比元组A低的最多只有一个,那么就输出(即它本身是最便宜的,那么比它价格还低的就只有0个;或者它是第二便宜的,那么价格比它低的就只有1个。这样一来,只要数量条件为<=1,那么就得到了最便宜的两种水果)

按照相关子查询的执行顺序,第一个元组符合条件,被输出。接下来,把第二个元组的值带入,如果符合条件则输出,接着第三个元组第四个元组... 直到所有的元组带入筛选完毕,整个查询过程也就结束了。

什么,你说价格排列没有顺序?加上order就可以了。
select type, variety, price
from fruits
where (
select count(*) from fruits as f
where f.type = fruits.type and f.price < fruits.price
) <= 1
order by fruits.type, fruits.price
 
1
select type, variety, price
2
from fruits
3
where (
4
   select count(*) from fruits as f
5
   where f.type = fruits.type and f.price < fruits.price
6
) <= 1
7
order by fruits.type, fruits.price
 

参考链接



如何用SQL实现组内前几名的输出的更多相关文章

  1. postgres select TOP X in group 查询每个组的前几名

    参考: https://stackoverflow.com/questions/27415706/postgresql-select-top-three-in-each-group http://ch ...

  2. mysql 分组取每个组的前几名的问题

    select *from hotel_addition_orders awhere (select count(*) from hotel_addition_orders where hotel_or ...

  3. 如何用sql批量删除一个id段内的dedecms文章?

    之前因为ytkah批量添加了dedecms文章,数量有些多,后面出现问题了,想要删除一部分织梦文章,后台一篇篇删,删到手软(相关内容:修改dedecms关键词到手软),于是就想到了sql数据库操作!那 ...

  4. [SQL]用于提取组内最新数据,左连接,内连接,not exist三种方案中,到底谁最快?

    本作代码下载:https://files.cnblogs.com/files/xiandedanteng/LeftInnerNotExist20191222.rar 人们总是喜欢给出或是得到一个简单明 ...

  5. sql查询技巧,按时间分段进行分组,每半小时一组统计组内记录数量

    今天拿到一个查询需求,需要统计某一天各个时间段内的记录数量. 具体是统计某天9:00至22:00时间段,每半小时内订单的数量,最后形成的数据形式如下: 时间段          订单数 9:00~9: ...

  6. sql 分组后显示每组的前几条记录

    sql 分组后显示每组的前几条记录 如   表中记录是             code       serialno             A1               1           ...

  7. sql server迁移数据(文件组之间的互相迁移与 文件组内文件的互相迁移)

    转自:https://www.cnblogs.com/lyhabc/p/3504380.html?utm_source=tuicool SQLSERVER将数据移到另一个文件组之后清空文件组并删除文件 ...

  8. sql 分组取每组的前n条或每组的n%(百分之n)的数据

    sql 分组取每组的前n条或每组的n%(百分之n)的数据 sql keyword: SELECT * ,ROW_NUMBER() OVER(partition by b.UserID order by ...

  9. 在论坛中出现的比较难的sql问题:29(row_number函数 组内某列的值连续出现3次标记出来)

    原文:在论坛中出现的比较难的sql问题:29(row_number函数 组内某列的值连续出现3次标记出来) 在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘 ...

随机推荐

  1. android之使用GridView+仿微信图片上传功能

    由于工作要求最近在使用GridView完成图片的批量上传功能,我的例子当中包含仿微信图片上传.拍照.本地选择.相片裁剪等功能,如果有需要的朋友可以看一下,希望我的实际经验能对您有所帮助. 直接上图,下 ...

  2. spring(四)之基于注解(Annotation-based)的配置.md

    注解 这里讲的注解有下面几个 @Autowired @Qualifier(" ") @Genre(" ") @Offline @Resource(name=&q ...

  3. 《Java从入门到放弃》JavaSE篇:程序结构

    程序的结构一般分为三种: 顺序结构. 选择结构. 循环结构. 一.顺序结构:这个不用多说吧,跟我们平时写文章的顺序一样,从上往下. 二.选择结构:从名字就能看出,要选择嘛,到底是要漂亮滴妹子,还是要有 ...

  4. java 面试,如何提升自己的实力,摘自 java web轻量级开发面试教程

    本内容摘自 java web轻量级开发面试教程 其中有一段讲述到了实习经验对找工作的帮助 1.2.2大学阶段的实习经验能帮到你 一般公司在筛选简历时,一个非常重要考察的要点是相关经验的工作年限,说一个 ...

  5. 【踩坑】activiti工作流的svg-xml解析报错

    1.问题记录 工作流配置画模板的时候保存成功但是部署报错. IE下 activiti工作流解析xml报错 type "path" must be followed by eithe ...

  6. ssh环境的搭建,基于注解和配置文件使用

    搭建spring.Struts2.hibernate三大框架的环境 这里分两部分来讲:一.用myeclipse 2014 快速搭建环境,非常快捷, 大部分配置文件信息系统都帮我们写好,建议老手使用 二 ...

  7. jQuery绑定事物处理器

    绑定与移除1..bind() 绑定事件可以有2个或者3个参数:第一个参数为事件类型 第二个参数为处理函数 第三个为布尔类型 on()事件代替2..delegate() 事件委托,三个参数,第一个为选择 ...

  8. grep Pocket Reference读记

    1 简介 grep的基本命令格式如下:           grep [options] [regexp] [filename]   如果regexp中含有空格,应该使用单引号或双引号括起来.单引号和 ...

  9. centos 7 最小安装后 安装FTP服务器 vsftp

    1.首先查看下 系统配置 rpm -q ftp #肯定是没安装, 2.安装 vsftpd yum -y vsftpd 3.vim /etc/vsftpd/vsftpd.conf anonymous_e ...

  10. clob字段的值插入和查询N种方法【包括java调用存储过程传入clob参数】

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import jav ...