ITPub博客

首页 > 数据库 > 数据库开发技术 > SQL教程#2Day:查询结果排序,order by?

SQL教程#2Day:查询结果排序,order by?

原创 数据库开发技术 作者:jackzhang 时间:2024-03-29 06:30:00 0 删除 编辑
“

教程所用示例表:关注并回复关键字“sql教程示例数据”即可获取,需要的朋友请自取。


引言

哈喽,欢迎来到SQL教程系列的第二讲——查询结果排序。本文的重点是自定义查询结果的输出形式。通过了解如何控制结果集的组织方式,你可以提供更具可读性和意义的数据。

结果集排序

按指定顺序返回查询结果

  • 问题:基于员工的薪水展示10号部门中所有员工的姓名、职位和薪水信息。
  • 实现:使用ORDER BY子句即可。
SELECT eName, job, sal
FROM emp
WHERE deptNo = 10
ORDER BY sal ASC;
  • 解释:ORDER BY子句允许对结果集中的行进行排序。上面的代码表示根据sal按升序对行进行排序。默认情况下,ORDER BY子句按升序排序,所以ASC关键字可省略。只有需要按降序排序的时候才需要显示指定排序方式,使用DESC关键字即可:
SELECT eName, job, sal
FROM emp
WHERE deptNo = 10
ORDER BY sal DESC;

上面的排序都是指定了列名,还有一种不用指定排序列名的方式可以实现相同的效果,即指定列在SELECT语句中的顺序编号(从1开始)。

SELECT eName, job, sal
FROM emp
WHERE deptNo = 10
ORDER BY 3 DESC;

🤖Tips:数字3表示对应SELECT语句中的第三列,即sal。但是推荐使用指定排序列名的方式,这样做不仅可读性更强,同时能避免后续代码维护的错误,比如修改了排序列在SELECT语句中的位置,但ORDER BY子句中的数字并未同步修改。

多字段排序

  • 问题:对员工表中的行排序,首先按部门号升序排序,然后再根据薪水降序排序。
  • 实现:在ORDER BY子句中列出不同的排序列,使用逗号分隔即可。
SELECT empNo, deptNo, sal, eName, job
FROM emp
ORDER BY deptNo, sal DESC;
  • 解释:ORDER BY的优先级顺序是从左到右。如果使用SELECT列表中列的数字位置进行排序的话,那么该数字不得大于SELECT列表中的列数。此外,也支持根据不在SELECT列表中的列进行排序,但这种情况你就必须显示地指定列名。但是切记,如果你在查询中使用了GROUP BY或DISTINCT子句,那么你就不可以将不在SELECT列表中的列用作排序列。

子串排序

  • 问题:根据字符串的指定部分对查询结果进行排序。例如,根据职位字段的最后两个字符排序输出员工的姓名和职位信息。
  • 实现:在ORDER BY子句中使用截取字符串的函数即可实现,DB2、MySQL、Oracle和PostgreSQL的字符串截取函数均为SUBSTR,而SQL Server的则是SUBSTRING。
SELECT eName, job
FROM emp
ORDER BY SUBSTR(job, LENGTH(job)-1);
  • 解释:使用DBMS自带的字符串截取函数,你可以很容易地根据字符串的任一部分对返回结果进行排序。SUBSTR函数的第二个参数为子串的起始位置,默认从所给起始位置一直到最后一个字符。如果是SUBSTRING函数,则还需要显式指定第三个参数,即截取的子串字符数量。

字母数字混合数据排序

  • 问题:假设你有混合的字母数字数据,并希望按数据的数字或字符部分排序。考虑以下根据emp表创建的视图:
DROP VIEW IF EXISTS V;
CREATE VIEW V
AS
SELECT CONCAT(eName, ' ', deptNo) AS data
FROM emp;

SELECT * FROM V;
  • 实现:分别按员工姓名和部门号排序输出。

Oracle、SQL Server和PostgreSQL

-- 按部门号排序
SELECT data
FROM V
ORDER BY REPLACE(data,
                 REPLACE(TRANSLATE(data, '0123456789', '#'), '#', ''), '');
-- 按员工姓名排序
SELECT data
FROM V
ORDER BY REPLACE(TRANSLATE(data, '0123456789', '#'), '#', '');

MySQL

-- 按部门号排序
SELECT data
FROM V
ORDER BY SUBSTRING_INDEX(data, ' ', -1);

-- 按员工姓名排序
SELECT data
FROM V
ORDER BY SUBSTRING_INDEX(data, ' ', 1);
  • 解释:TRANSLATE和REPLACE函数可以将每行中的数字或字符删除,这样就可以轻松地按其中一个排序。根据目的结合灵活使用即可。

排序时空值处理

  • 问题:现在假设你想根据comm列对emp的结果进行排序,但是comm是可以允许空值(NULL)存在的,所以你需要指定空值的排序位置(开头或结尾)。
  • 实现:如果只是想实现空值排序位置的话,可以简单通过排序关键字实现即可。升序方式默认空值排开头,反之降序则默认将空值排在结尾。
-- 空值排在最后
SELECT eName, sal, comm
FROM emp
ORDER BY comm DESC ;
-- 空值排在开头
SELECT eName, sal, comm
FROM emp
ORDER BY comm;

但是如果想实现空值排序位置的同时,还想控制comm的排序方式的话,就需要借助辅助列实现,使用CASE表达式即可。

DB2、MySQL、PostgreSQL和SQL Server

-- 非空comm升序,所有null排最后
SELECT eName, sal, comm
FROM (SELECT eName,
             sal,
             comm,
             CASE WHEN comm IS NULL THEN 0 ELSE 1 END AS is_null
      FROM emp) t
ORDER BY is_null DESC, comm;
-- 非空comm升序,所有null排开头
SELECT eName, sal, comm
FROM (SELECT eName,
             sal,
             comm,
             CASE WHEN comm IS NULL THEN 0 ELSE 1 END AS is_null
      FROM emp) t
ORDER BY is_null, comm;
-- 非空comm降序,所有null排开头
SELECT eName, sal, comm
FROM (SELECT eName,
             sal,
             comm,
             CASE WHEN comm IS NULL THEN 0 ELSE 1 END AS is_null
      FROM emp) t
ORDER BY is_null, comm DESC;
-- 非空comm降序,所有null排最后
SELECT eName, sal, comm
FROM (SELECT eName,
             sal,
             comm,
             CASE WHEN comm IS NULL THEN 0 ELSE 1 END AS is_null
      FROM emp) t
ORDER BY is_null DESC, comm DESC;

Oracle
Oracle有关键字支持null的排序位置(开头-NULLS FIRST;最后-NULLS LAST):

-- 非空comm升序,所有null排最后
SELECT ENAME, MSAL, COMM
FROM EMPLOYEES
ORDER BY COMM NULLS LAST;

其他三种排序组合在ORDER BY子句中相应更改即可。

  • 解释:如果你的DBMS不是Oracle的话,就需要借助辅助列实现上述集中排序。而且从代码移植性角度考虑,也是后者更适用,因为可以在不更改代码的情况下跨平台运行。

根据条件逻辑排序

  • 问题:假设你想基于某些条件逻辑进行排序。比如,对于emp表,如果职位是销售人员(salesman),根据comm列排序,否则根据sal列排序。
  • 实现:在ORDER BY子句中使用CASE表达式即可实现按条件根据不同列排序。
SELECT eName, sal, job, comm
FROM emp
ORDER BY CASE WHEN job = 'SALESMAN' THEN comm ELSE sal END;
  • 解释:可以在ORDER BY子句中使用CASE表达式动态改变排序列。

结论

对查询结果进行排序是SQL用户必须掌握的核心技能之一。ORDER BY子句可以非常强大,但是正如我们在本文中所看到的,要想有效地使用,仍然需要经常注意一些细微的差别。因此掌握结果排序至关重要,因为后面教程中许多地方都依赖于它,同时日常工作中也会经常用到。

“

如果你觉得这篇文章对你有用,请“点赞➕在看➕分享➕关注”支持我(关注我,不迷路🤭🤭🤭),你的点赞和关注就是我持续创作分享的动力,让更多的朋友发现并加入我们,共同学习和进步!

Thank you for reading!

- END -

推荐阅读👇👇👇

SQL教程#1Day:数据检索

2024年数据分析师都应该知道的5个高级SQL概念

13个SQL语句:解决90%的数据科学问题!你都知道哪些?

2024年SQL从新手到高手学习路线:附学习资源(赶紧收藏~~)

SQL连接最全总结:提升你的数据库查询技能(建议收藏)

原文作者:数据派探险家;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2017-12-19

  • 博文量
    119
  • 访问量
    55955