排序检索数据库
本章将讲述如何使用SELECT语句的ORDER BY子句,根据需要排序检索出的数据。
5.1排序数据
正如前一章所述,下面SQL语句返回某个数据库表的单个列,但其输出没有特定的顺序
SELECT e.`ename`
FROM
emp e
;
其实检索出的数据并不是以纯粹的随机顺序显示的。如果不排序,数据一般将它在底层表中出现的顺序显示。这可能是数据最初添加到表中的顺序。但是,如果数据后来进行过更新或者删除,则此顺序将会受到MySQL重用回收存储空间的影响。因此,如果不明确控制的话,不能(也不应该)依赖该排序顺序。关系数据库设计理论认为,如果不明确排序顺序,则不应该假定见所处的数据的顺序有意义。
子句(clause) SQL语句由子句构成,有些子句是必需的,而有的是可选的。一个子句通常由一个关键字和所提供的数据组成。子句的例子有SELECT语句的FROM子句,我们在以前看到过这个子句(SHOW COLUMNS FROM 表名)
为了明确的排序用SELECT语句检索出的数据,可以使用ORDER BY子句。ORDER BY子句取一个或多个列的名字,据此对输出进行排序。请看下面的例子。
SELECT e.`id`
FROM emp e
ORDER BY e.`id`
;
通过非选择排列进行排序:通常 ORDER BY子句中使用的列将是为显示所选择的列。但是,实际上并不一定要这样,用非检索的列排序数据也是完全可以的。
5.2排序多个列
经常要按照不止一个列进行数据排序。例如,如果要显示雇员清单,可能希望按照姓和名排序(首先按照姓排序,如果姓相同再按照名排序)。如果多个雇员具有相同的姓,这样做很有用。
为了按多个列排序,只要指定列名,列名之间用逗号分开即可(就像选择多个列的时候所做的那样)。
下面的代码检索3个列,并按照其中两个列对结果进行排序,首先按照工资,然后按照id排序。
SELECT e.`salary`,e.`id`
FROM emp e
ORDER BY e.`salary`,e.`id`
;
重要的是理解在按多个列排序的时候,排序完全按照所规定的顺序进行。换句话说,对于上述例子中的输出,仅在多个行具有相同的salary的时候才按照id排序。如果salary的值都是唯一的,就不会按照id排序。
5.3指定排序方向
数据排序不限于升序排序(从A到Z),这只是默认的排序。还可以使用ORDER BY子句进行降序(从Z到A)顺序排序。为了进行降序排序,必须指定DESC关键字。
SELECT e.`salary`,e.`id`,e.`ename`
FROM emp e
ORDER BY e.`salary` DESC
;
但是,如果打算用多个列排序怎么办?下面的例子以降序排列薪水(最贵的在前面),然后在按照id升序排列(同样的薪水,id最小的在前面)
SELECT e.`salary`,e.`id`,e.`ename`
FROM emp e
ORDER BY e.`salary` DESC,e.`id`
;
DESC关键字只应用到直接位于其前面的列名。在上例中,只对e.salary列指定DESC,对于e.id列不指定。因此,salary列以降序排序,id列以升序排列(在相同价格的时候)。
如果想在多个列上进行降序排序,必须对每个列指定DESC关键字。
与DESC相反的关键字是ASC(ASCENDING),在升序排序的时候可以指定它,实际上,ASC没有多大用处,因为升序是默认的(如果既不指定ASC,也不指定DESC),默认当做ASC.
区分大小写和排序顺序。在对文本性的数据进行排序的时候,A与a相同吗?a位于B之前还是位于Z之后?这些问题不是理论问题,其答案取决于数据库如何设置。
在字典排序顺序中,A被视为和a相同(因为SQL大小写不敏感)。但是数据库管理员能在需要的时候改变这种行为。
使用ORDER BY和LIMIT的组合,能够找出一个列中最高或者最低的值。下面的例子演示如何找出最工资最高的几个人的工资
SELECT e.`salary`,e.`id`,e.`ename`
FROM emp e
ORDER BY e.`salary` desc,e.`id`
LIMIT 5
;
使用子句的次序要注意,保证FROM子句在ORDER BY子句之前,ORDER BY子句在LIMIT子句之前。子句顺序不对的话讲产生错误信息。
小结
本章学习了如何使用SELECT语句的ORDER BY子句对检索出的数据进行排序。这个子句必须是SELECT语句中的最后一条子句。可以更具需要,利用它在一个或者多个列上对数据进行排序。