MySQL 组内查询第N项/前N项

一 引言

上一篇  Mysql 排序查询第N项 / 前N项(三种方法)已经总结了取前N项和倒数前N项的问题,这一篇主要解决分组后查询前N项/第N项问题

例如:查询每个员工最高薪资/每个员工第二薪资/每个员工最低薪资/各个品类销量前十的商品

二 Group By 的作用

说到分组,一般离不开group by语句。所以我们先看看group by到底有什么作用

1. group by直接使用,不搭配聚合函数(sum,average,count等),结果是取出每个分类字段的第一条记录(这里的分类字段是emp_no)

分组前 
分组后

2. 搭配聚合函数(sum,average,count等),结果是根据分类字段进行加总、平均、计数

三 每个员工的最高工资和最低工资

根据员工编号emp_no汇总

四 每个员工的第二高工资

1. 为什么不能用 group by+ order by +limit

因为  limit 1,1 只能取出整个表的第二行,不能分组取各个组的第二行

2. 排名法

其实就是Mysql 排序查询第N项 / 前N项(三种方法)里面的排名法。原理:假如 a 排第10,意味着前面有9个数比a大,有10个数大于等于a, 求某个数的排名就是求前面有几个数大于等于这个数

思路:重复用salaries表,命名为s1,s2。用where语句s1.salary<=s2.salary筛选出所有大于等于s1.salary的s2.salary。然后统计每个s1.salary有多少个s2.salary大于等于它,就能得到每个s1.salary的排名

那么分组取第N项的排名法和上文有什么不一样呢。区别在于:排序查询前N项时,s1.salary<=s2.salary筛选出的是全表所有薪资中大于等于s1.salary的s2.salary。而我们要的是员工和自己的其他工资对比,是在员工自己的历史工资里面筛选,而不是在全表所有员工薪资里面筛选。转化为mysql语言就是,要在以员工编号为依据的分组里面筛选。因此,这里的排名法多了一个条件  s1.emp_no = s2.emp_no。


2.1 第一步

重复使用salaries表,分别命名为s1,s2。用 where s1.emp_no = s2.emp_no 将两个相同的表连接

保证只有员工编号相同的s1.salary 和s2.salary才能匹配上。

2.2 第二步

增加where条件:s1.salary<=s2.salary。 筛选出所有小于等于s1.salary 的 s2.salary 

2.3 第三步 

统计每个s1.salary有几个小于等于它的s2.salary,也就是s1.salary的排名

2.4 完整代码

不用group by 。 

五  每个员工的倒数第二工资

方法和上面一样,只是把s1.salary<=s2.salary 换成s1.salary >= s2.salary

另一种写法

不用group by 



六  每个员工最低工资减去第二低工资

思路:查出每个员工的最低工资,作为临时表a,查出每个员工的第二低工资作为临时表b。将a,b作为from 的子查询,用where 语句关联两个表

不用group by 

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • mysql数据库中 :database : 文件夹table : 数据表(数据文件) 进入mysqlmysql -...
    赋闲阅读 591评论 0 0
  • 1. 了解SQL 1.1 数据库基础 ​ 学习到目前这个阶段,我们就需要以某种方式与数据库打交道。在深入学习MyS...
    锋享前端阅读 1,172评论 0 1
  • ORACLE自学教程 --create tabletestone ( id number, --序号usernam...
    落叶寂聊阅读 1,162评论 0 0
  • 一. Java基础部分.................................................
    wy_sure阅读 3,870评论 0 11
  • 怎么讲,觉得SQL是一门 “一看就懂,一学就会,一做就错”的语言. 这回是第…三…次SQL(上过两次SQL的课,两...
    锅锅Iris阅读 573评论 0 0