MySQL 选择前n个记录

备注:测试数据库版本为MySQL 8.0

如需要scott用户下建表及录入数据语句,可参考:
scott建表及录入数据sql脚本

一.需求

一某种排序方式,限定结果集只包含一定数目的记录。
例如,返回最高5档工资的员工姓名和工资。

二.解决方案

这种解决方案的关键是两个步骤: 首先按预定方式给行排序,然后限定结果集,只包含感兴趣的行。

2.1 标量子查询方法

使用标量子查询,为每个工资创建一个等级。然后利用等级限制子查询的结果:

select ename,sal
  from (
select ( select count(distinct b.sal)
           from emp b
         where a.sal <= b.sal) as rnk,
       a.sal,
       a.ename
  from emp a
        ) x
where rnk <= 5;

测试记录:

mysql> select ename,sal
    ->   from (
    -> select ( select count(distinct b.sal)
    ->            from emp b
    ->          where a.sal <= b.sal) as rnk,
    ->        a.sal,
    ->        a.ename
    ->   from emp a
    ->         ) x
    -> where rnk <= 5;
+-------+---------+
| ename | sal     |
+-------+---------+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING  | 5000.00 |
| FORD  | 3000.00 |
+-------+---------+
6 rows in set (0.00 sec)

2.2 MySQL 8.0 窗口函数方法

MySQL窗口函数功能更强大,代码更简洁

select ename,sal
  from (
select ename,sal,
       dense_rank() over w  as 'dr'
  from emp
  window w as (order by sal desc) 
  ) x
where dr <= 5
;

测试记录:

mysql> select ename,sal
    ->   from (
    -> select ename,sal,
    ->        dense_rank() over w  as 'dr'
    ->   from emp
    ->   window w as (order by sal desc)
    ->   ) x
    -> where dr <= 5
    -> ;
+-------+---------+
| ename | sal     |
+-------+---------+
| KING  | 5000.00 |
| SCOTT | 3000.00 |
| FORD  | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
+-------+---------+
6 rows in set (0.00 sec)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值