1. 默认情况下,ORDER BY会做升序排列,因此ASC子句是可选的。可以通过DESC执行降序排列。可以再ORDER BY子句中列出不同的排序列,逗号分隔。
一般而言,可以根据一个没有被包含在SELECT列中的列来排序,但是必须明确地指定列名。但是当查询语句中含有GROUP BY或者DISTINCT,那么不能按照SELECT列表之外的列进行排序。该问题可参考《小白学习MySQL - only_full_group_by的校验规则》。
2. 依据子串排序
按照职位字段后3个字符进行排序,
DB2、MySQL、Oracle、PG,
代码语言:javascript复制select ename,job
from emp
order by substr(job,length(job)-2);
SQL Server,第三个参数,既可以是2,还可以大于2,
代码语言:javascript复制select ename,job
from emp
order by substring(job,len((job)-2,2);
3. 如果字段混合了字母和数字,其中按照字母或者数字进行排序,例如,
代码语言:javascript复制create view V
as
select ename||' '||deptno as data
from emp;
使用translate函数和replace函数删除每一行的数字或者字符,即可按照剩余的部分排序。
需求按照ename或者deptno进行排序,
Oracle、PG,按照deptno排序,
代码语言:javascript复制select data
from V
order by replace(data,
replace(
translate(data, '0123456789','##########','#',''),'');
按照ename排序,
代码语言:javascript复制select data
from V
order by replace(
translate(data,'0123456789','##########','#','');
DB2,按照deptno排序,
代码语言:javascript复制select *
from (
select ename||' '||cast(deptno as char(2)) as data
from emp
) v
order by replace(data,
replace(
translate(data,'##########','01234567890',),'#',''),'');
按照ename排序,
代码语言:javascript复制select *
from (
select ename||' '||cast(deptno as char(2)) as data
from emp
) v
order by replace(data,
translate(data,'##########','01234567890',),'#','');
MySQL和SQL Server不支持translate函数。
4. NULL的排序
DB2、MySQL、PG和SQL Server,需要增加辅助列,
非Null值按照comm升序排列,全部Null值放到最后,删除desc,则放到最前,
代码语言:javascript复制select ename, sal, comm
from (
select ename, sal, comm,
case when comm is null then 0 else 1 end as is_null
from emp
) x
order by is_null desc, comm;
Oracle,提供了特殊语法,无需考虑非Null值的排序方式,
非Null值comm升序排列,全部Null值放到最后,
代码语言:javascript复制select ename, sal, comm
from emp
order by comm nulls last;
非Null值comm升序排列,全部Null值放到最前,
代码语言:javascript复制select ename, sal, comm
from emp
order by comm nulls first;
5. 依据条件逻辑动态调整排序项
例如,如果job等于salesman,就需要按照comm排序,否则,就按照sal排序,此时用到case...when...子句,
代码语言:javascript复制select ename, sal, job, comm
from emp
order by case when job='SALESMAN' then comm else sal end;
或者,
代码语言:javascript复制select ename, sal, job, comm,
case when job='SALESMAN' then comm else sal end as ordered
from emp
order by 5;