美文网首页
MySQL 轮换行值

MySQL 轮换行值

作者: 只是甲 | 来源:发表于2020-11-12 09:12 被阅读0次

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

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

    一.需求

    返回每个员工的姓名和工资以及低于自己的最高工资和高于自己的最低工资。如果没有更高或最低的工资,则可能要求结果环绕(即第一个SAL显示最后一个SAL,反之亦然。)

    要求输出如下:
    +--------+---------+---------+---------+
    | ename | sal | forward | rewind |
    +--------+---------+---------+---------+
    | SMITH | 800.00 | 950.00 | 5000.00 |
    | JAMES | 950.00 | 1100.00 | 800.00 |
    | ADAMS | 1100.00 | 1250.00 | 950.00 |
    | WARD | 1250.00 | 1300.00 | 1100.00 |
    | MARTIN | 1250.00 | 1300.00 | 1100.00 |
    | MILLER | 1300.00 | 1500.00 | 1250.00 |
    | TURNER | 1500.00 | 1600.00 | 1300.00 |
    | ALLEN | 1600.00 | 2450.00 | 1500.00 |
    | CLARK | 2450.00 | 2850.00 | 1600.00 |
    | BLAKE | 2850.00 | 2975.00 | 2450.00 |
    | JONES | 2975.00 | 3000.00 | 2850.00 |
    | SCOTT | 3000.00 | 5000.00 | 2975.00 |
    | FORD | 3000.00 | 5000.00 | 2975.00 |
    | KING | 5000.00 | 800.00 | 3000.00 |
    +--------+---------+---------+---------+

    二.解决方案

    2.1 子查询方法

    使用标量子查询,找到相对于每个工资的下一档工资和上一当工资:

    select  e.ename, e.sal,
            coalesce(
               (select min(sal) from emp d where d.sal > e.sal),
               (select min(sal) from emp)
            ) as forward,
            coalesce(
               (select max(sal) from emp d where d.sal < e.sal),
               (select max(sal) from emp)
            ) as rewind
        from emp e
    order by 2;
    

    测试记录

    mysql> select  e.ename, e.sal,
        ->         coalesce(
        ->            (select min(sal) from emp d where d.sal > e.sal),
        ->            (select min(sal) from emp)
        ->         ) as forward,
        ->         coalesce(
        ->            (select max(sal) from emp d where d.sal < e.sal),
        ->            (select max(sal) from emp)
        ->         ) as rewind
        ->     from emp e
        -> order by 2;
    +--------+---------+---------+---------+
    | ename  | sal     | forward | rewind  |
    +--------+---------+---------+---------+
    | SMITH  |  800.00 |  950.00 | 5000.00 |
    | JAMES  |  950.00 | 1100.00 |  800.00 |
    | ADAMS  | 1100.00 | 1250.00 |  950.00 |
    | WARD   | 1250.00 | 1300.00 | 1100.00 |
    | MARTIN | 1250.00 | 1300.00 | 1100.00 |
    | MILLER | 1300.00 | 1500.00 | 1250.00 |
    | TURNER | 1500.00 | 1600.00 | 1300.00 |
    | ALLEN  | 1600.00 | 2450.00 | 1500.00 |
    | CLARK  | 2450.00 | 2850.00 | 1600.00 |
    | BLAKE  | 2850.00 | 2975.00 | 2450.00 |
    | JONES  | 2975.00 | 3000.00 | 2850.00 |
    | SCOTT  | 3000.00 | 5000.00 | 2975.00 |
    | FORD   | 3000.00 | 5000.00 | 2975.00 |
    | KING   | 5000.00 |  800.00 | 3000.00 |
    +--------+---------+---------+---------+
    14 rows in set (0.00 sec)
    

    2.2 MySQL 8.0 窗口函数方法

    select ename ,sal ,
           coalesce(lead(sal) over w1,min(sal) over w2) forward,
           coalesce(lag(sal) over w1,max(sal) over w2) rewind
    from emp
    window w1 as (order by sal),
           w2 as ()
    ;
    

    测试记录

    mysql> select ename ,sal ,
        ->        coalesce(lead(sal) over w1,min(sal) over w2) forward,
        ->        coalesce(lag(sal) over w1,max(sal) over w2) rewind
        -> from emp
        -> window w1 as (order by sal),
        ->        w2 as ()
        -> ;
    +--------+---------+---------+---------+
    | ename  | sal     | forward | rewind  |
    +--------+---------+---------+---------+
    | SMITH  |  800.00 |  950.00 | 5000.00 |
    | JAMES  |  950.00 | 1100.00 |  800.00 |
    | ADAMS  | 1100.00 | 1250.00 |  950.00 |
    | WARD   | 1250.00 | 1250.00 | 1100.00 |
    | MARTIN | 1250.00 | 1300.00 | 1250.00 |
    | MILLER | 1300.00 | 1500.00 | 1250.00 |
    | TURNER | 1500.00 | 1600.00 | 1300.00 |
    | ALLEN  | 1600.00 | 2450.00 | 1500.00 |
    | CLARK  | 2450.00 | 2850.00 | 1600.00 |
    | BLAKE  | 2850.00 | 2975.00 | 2450.00 |
    | JONES  | 2975.00 | 3000.00 | 2850.00 |
    | SCOTT  | 3000.00 | 3000.00 | 2975.00 |
    | FORD   | 3000.00 | 5000.00 | 3000.00 |
    | KING   | 5000.00 |  800.00 | 3000.00 |
    +--------+---------+---------+---------+
    14 rows in set (0.00 sec)
    
    

    相关文章

      网友评论

          本文标题:MySQL 轮换行值

          本文链接:https://www.haomeiwen.com/subject/ammkmktx.html