在做项目的过程中会遇到不同情况的排序,如对某个字段根据该字段的不同值进行排序:
如需要对一张表的status字段按照1,0,2的顺序排序,这个时候就不能使用传统的asc进行排序了:
select * from t where type = 2 order by status asc;
而是要按照该字段的值进行排序:
select * from ttt where type = 2 ORDER BY FIELD('status',1,0,2);
相应在mysbatis中的排序
tttExample.setOrderByClause("field('status', 1,0,2)");
另外一种方法是使用case when来指定排序
例如一张表有一个字段是status,其字典为0,1,2,但是现在需要按照status值1,0,2的顺序排序,可以这样做
select * from t where type = 2 order by case
when 'status'=0 then 1
when 'status'=1 then 2
when 'status'=2 then 3
end asc;
case when 自定义排序时的使用
根据 case when 新的 sort字段排序
case
when t2.status = 4
and t2.expire_time>UNIX_TIMESTAMP()
and t2.expire_time<UNIX_TIMESTAMP(DATE_ADD(NOW(),INTERVAL 60 day)) then 4
when `status` = 2 then 3
when `status` = 3 then 2
when t2.status = 4
and t2.expire_time>UNIX_TIMESTAMP(DATE_ADD(NOW(),INTERVAL 60 day))
and t2.expire_time<UNIX_TIMESTAMP(DATE_ADD(NOW(),INTERVAL 1 year)) then 1
else 0
end sort
$query->orderBy('sort desc ,t2.expire_time desc,t2.created_at desc');
- 当colume 与condition 条件相等时结果为result
-
case colume when condition then result when condition then result when condition then result else result end
- 当满足某一条件时,执行某一result,把该结果赋值到new_column_name 字段中
一个更复杂的排序场景
需要对一张表进行排序,排序规则如下:
1、先按照status字段的值1,0,2的顺序排序;
2、再按照status为1的时候,按照orderId倒序排序;
3、再按照status为0的时候,按照onlineTime顺序排序;
4、再按照status为2的时候,按照updateTime倒序排序
5、最后还需要支持分页。
对于该场景可以使用两种方式来进行排序:
(1)使用联合查询的方式来排序:
select * from(
(select * from t where type = 2 and status = 1 order by orderId desc limit 99999999)
union all
(select * from t where type = 2 and status =0 order by onlineTime asc limit 99999999)
union all
(select * from t where type = 2 and status =2 order by update desc limit 99999999)
)limit 99999999;
(2)使用case when来进行排序;
SELECT
t.*, (
CASE t.STATUS
WHEN 1 THEN 1
WHEN 0 THEN 2
WHEN 2 THEN 3
END
) AS status_tmp
FROM t where type = 2
ORDER BY
status_tmp ASC,
CASE WHEN t. STATUS = 1 THEN t.orderId END DESC,
CASE WHEN t. STATUS = 0 THEN t.onlineTime END ASC,
CASE WHEN t. STATUS = 2 THEN t.updateTime END DESC
对于第一中实现方式看起来会非常丑陋,但是对于第二种方式则会好很对,也不容易引起误解