本章主要内容:
1,常规排序
2,自定义排序
3,排序的扩展应用:提取前n大或后n小的记录
1.
排序是我们使用Excel处理数据经常面对的问题,Excel甚至专门对此内置了【排序】功能。今天,我们就来聊一下SQL如何对查询结果进行排序操作,也就是ORDER BY 语句,其语法如下:
SELECT 字段名 FROM 表名 ORDEY BY 字段名
该语句默认对记录进行升序排序,如果需要降序排序,可以使用关键字DESC:
SELECT 字段名 FROM 表名 ORDEY BY 字段名 DESC
照例举个小例子。
如下图所示,工作表名称为“销售表”,A列是月份,B列是产品,C列是生产量,D列是销售量,数据纯属虚拟,如有雷同——实属雷人。
如果我们需要查询该表月份和销售量两个字段的数据,并将销售量作升序排列,代码如下:
SELECT 月份,销售量 FROM [销售表$] ORDER BY 销售量
如果我们需要查询月份、生产量、销售量三个字段的数据,其中生产量优先排序,且降序排列,销售量升序排列,代码如下:
SELECT 月份,生产量,销售量 FROM [销售表$] ORDER BY生产量 DESC,销售量 ASC
也就是说,ORDER BY语句中,优先排序的字段放在前面,不同字段可以指定不同的排序规则,如果没有指定排序规则,则默认为升序(ASC)排列。
代码结果如下:
2.
依然使用上一节的例子,倘若我们需要对查询结果按月份进行降序排列,可能有些朋友代码会写成如下这般:
SELECT 月份,销售量 FROM [销售表$] ORDER BY 月份 DESC
但发现结果和我们想的并不一样。
月份的排列看起来完全是乱态的,既不是升序也不是降序。
上一章我们提过,SQL In Excel对简体中文排序的规则不走寻常路,既不按拼音字母排序,也不按笔画排序,而是可能和其它数据库一样,采用的Chinese_PRC针对大陆简体字UNICODE的排序规则,但和其它数据库所不同的是,我们没有修改该规则参数的权限,以达到拼音或笔划排序的目的……
不过,事实上,即便是使用Excel自带的排序功能(默认拼音字母排序),排序结果也并非是五四三二一月。
此时我们需要自定义排序规则,也就是使用SQL中的iif或者instr函数。
IF函数类似于工作表的IF函数,语法如下:
=IIF(条件表达式,真值结果,假值结果)
使用IIF自定义排序规则的SQL语句如下:
SELECT 月份,销售量 FROM [销售表$] ORDER BYIIF(月份='五月',1,IIF(月份='四月',2,IIF(月份='三月',3,IIF(月份='二月',4,IIF(月份='一月',5)))))
代码长的吓人?
但意思其实很简单。
……如果月份等于五月,就返回1,否则如果月份等于四月,就返回2,再否则如果月份等于三月……以此类推……最后ORDER BY语句按IIF返回的结果进行升序排序……
看了这个代码,是不是瞬间找回当年嵌套N层IF函数的青葱小岁月……
再说下INSTR函数。
INSTR函数有些类似于工作表函数FIND,查找一个字符串在另一个字符串中的位置,和FIND不同的是,当找不到相关值时,结果返回0,而非错误值。
INSTR(str, substr)。返回substr在str中的位置,若不存在,则返回0。
使用INSTR函数自定义排序规则的SQL语句如下:
SELECT 月份,销售量 FROM [销售表$] ORDER BY INSTR('五月,四月,三月,二月,一月',月份)
查询结果如下:
INSTR函数的处理语句比起IIF函数来明显要简洁清爽的多。
——因此我们通常使用该函数处理自定义排序的问题。
3.
提一个问题,如下。
如果使用SQL语句查询上述示例中,销售量前三名的月份和销售量,该怎么表述呢?
……
不要想的太复杂,其实很简单。
在原本对销量进行降序排序的结果上,提取前三行的记录就OK。
如何提取前3行记录呢?
可以使用关键词TOP。
TOP n 指定检索结果集中的第n行前的记录。
完整SQL代码如下:
SELECT TOP 3 月份,销售量 FROM [销售表$] ORDER BY 销售量 DESC
查询结果如下:
那么如果查询销售量后二名的月份和销量呢?
4.我们今天分享了一个语句(ORDER BY)一个关键字(TOP)两个函数(IIF、INSTR)
耸肩,摊手,你看——相比于函数,SQL语言在处理去重复、排序、自定义排序、提取前n名数据的问题上,是不是简单太多了?
不要困在Excel函数那一个小天地里,它的性能决定了它的功能很有限,更不要迷恋数组公式,除了预防老年痴呆它别无用处……
只学一点VBA(循环),或学一点SQL(SELECT子句),处理实际问题的能力也强过n多所谓的函数高手。
VBA编程学习与实践
领取专属 10元无门槛券
私享最新 技术干货