《SQL Cookbook》 - 第二章 查询结果排序

Posted bisal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《SQL Cookbook》 - 第二章 查询结果排序相关的知识,希望对你有一定的参考价值。

1. 默认情况下,ORDER BY会做升序排列,因此ASC子句是可选的。可以通过DESC执行降序排列。可以再ORDER BY子句中列出不同的排序列,逗号分隔。

一般而言,可以根据一个没有被包含在SELECT列中的列来排序,但是必须明确地指定列名。但是当查询语句中含有GROUP BY或者DISTINCT,那么不能按照SELECT列表之外的列进行排序。该问题可参考《小白学习MySQL - only_full_group_by的校验规则》。

2. 依据子串排序

按照职位字段后3个字符进行排序,

DB2、mysql、Oracle、PG,

select ename,job
  from emp
 order by substr(job,length(job)-2);

SQL Server,第三个参数,既可以是2,还可以大于2,

select ename,job
  from emp
 order by substring(job,len((job)-2,2);

3. 如果字段混合了字母和数字,其中按照字母或者数字进行排序,例如,

create view V
    as
select ename||' '||deptno as data
  from emp;

使用translate函数和replace函数删除每一行的数字或者字符,即可按照剩余的部分排序。

需求按照ename或者deptno进行排序,

Oracle、PG,按照deptno排序,

select data
 from V
 order by replace(data,
               replace(
             translate(data, '0123456789','##########','#',''),'');

按照ename排序,

select data
  from V
 order by replace(
               translate(data,'0123456789','##########','#','');

DB2,按照deptno排序,

select *
  from (
select ename||' '||cast(deptno as char(2)) as data
  from emp
          ) v
 order by replace(data,
               replace(
             translate(data,'##########','01234567890',),'#',''),'');

按照ename排序,

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,则放到最前,

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值放到最后,

select ename, sal, comm
  from emp
 order by comm nulls last;

非Null值comm升序排列,全部Null值放到最前,

select ename, sal, comm
  from emp
 order by comm nulls first;

5. 依据条件逻辑动态调整排序项

例如,如果job等于salesman,就需要按照comm排序,否则,就按照sal排序,此时用到case...when...子句,

select ename, sal, job, comm
  from emp
 order by case when job='SALESMAN' then comm else sal end;

或者,

select ename, sal, job, comm,
          case when job='SALESMAN' then comm else sal end as ordered
  from emp
 order by 5;

《SQL Cookbook》读书笔记:

《SQL Cookbook》 - 第一章 检索数据

近期更新的文章:

《SQL Cookbook》 - 第一章 检索数据

梅西 ≠ 一人一城?

小白学习MySQL - 表空间碎片整理方法

Oracle字符串类型扩容隐患

PG逻辑复制的REPLICA IDENTITY设置

文章分类和索引:

《公众号800篇文章分类和索引

以上是关于《SQL Cookbook》 - 第二章 查询结果排序的主要内容,如果未能解决你的问题,请参考以下文章

SQL Cookbook:操作多个表

将第二个表中的第二个(条件)结果添加到 SQL 查询

我雄辩的查询构建器实例返回空,而 sql 子句返回结果。会欣赏第二只眼睛

SQL 限制查询结果

根据第二个查询中的时间对两个查询的结果进行排序[关闭]

将SQL表的两次查询结果作求交运算