August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
MySQL order by基于不同字段条件排序
发布:2023年03月02日 | 作者:augustrush | 阅读量: 542

从数据库上查询数据的时候,按要求排序,在某个字段的不同值的基础上再选择不同的字段进行排序,具体描述如下:

1. 首先有一个基础字段statusstatus的取值分别为1234

2. 先对status进行排列,但是要求顺序为:2134(其实每个值都代表一种含义,简单处理就是,将12代表的含义调换位置,那就不用对这个字段做处理直接升序就ok了,这里为了复杂一点,就这样定义。)

3. 如果status为1,按follow_up_time做降序

    如果status为2,按follow_up_time做降序,若follow_up_time为空,则按appointment_time降序

    如果status为3,按next_follow_up_time做降序

    如果status为4,按final_follow_up_time做升序


具体实现如下,先贴出来SQL,再进行解释

SELECT
    *
FROM
    t_user_appointment
ORDER BY
    CASE WHEN `status` = 2 THEN 0 ELSE 4 END ASC,
    `status` ASC,
    CASE WHEN `status` = 1 THEN follow_up_time END DESC,
    CASE WHEN `status` = 2 
                    THEN (CASE WHEN follow_up_time IS NULL THEN appointment_time ELSE follow_up_time END) END,
    CASE WHEN `status` = 3 THEN next_follow_up_time END DESC,
    CASE WHEN `status` = 4 THEN final_follow_up_time END ASC;


从order by后面逐句开始:

1.   `CASE WHEN status = 2 THEN 0 ELSE 4 END ASC,`
     如果status=2时,那就将status为2的视为0,其他的视为4,进行一次升序排序
2.   `status ASC,`
     此时status=2已经视为0了,那再对status进行一次升序,逻辑上status顺序为:0、1、3、4,则实际为:2、1、3、4了
3.   `CASE WHEN status = 1 THEN follow_up_time END DESC,`
     已经对status排好序了,现在对不同值的status的数据进行排序。如果status=1时,按follow_up_time做降序。
4.   `CASE WHEN status = 2 THEN (CASE WHEN follow_up_time IS NULL THEN appointment_time ELSE follow_up_time END) END,`
     如果status=2时,按follow_up_time做降序,若follow_up_time为空,则按appointment_time降序,这里使用了双层case when,内层的case when选择出到底用哪个字段排序。
5.   `CASE WHEN status = 3 THEN next_follow_up_time END DESC,`
     如果status=3时,按next_follow_up_time做降序
6.   `CASE WHEN status = 4 THEN final_follow_up_time END ASC;`
     如果status=4时,按final_follow_up_time做升序


tips:

不合理的order by,会很大程度降低SQL的性能,以下为摘抄的几点建议:

1. ORDER BY的字段改到一张表,不要跨表(设计表结构时需要注意这一点)
2. ORDER BY字段建立索引、多个字段时建立联合索引(联合索引的字段顺序要与ORDER BY中的字段顺序一致)
3. ORDER BY中字段中联合索引的所有字段DESC或ASC要统一,否则索引不起作用
4. 不要对TEXT字段或者CLOB字段进行排序


  • 标签云

  • 支付宝扫码支持一下

  • 微信扫码支持一下



基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed