11.分组和排序

通过上一节的学习,我们掌握了单表查询的基本技能,但是针对一些特殊的场景还是没有解决的办法,比如如何来对查询的结果进行排序、如何按照某种规则来查询数据,这里我们就针对数据的排序、数据分组给大家做相应的解释。

数据排序

数据排序是数据查询中需要我们掌握的基本技能之一,实现数据查询结果的排序,我们可以按照如下方式来实现:

SELECT 列名 [AS] [别名] , 列名 [AS] [别名] FROM 表名 ORDER BY 列名 [ASC | DESC];

这里我们首先来查询一下user表中用户编号、用户名、用户密码这些信息,具体执行情况如下所示:

家可以看到,我们在用户表中一共有五条数据,现在我们想要让查询的结果在显示的时候,用户编号按照从大到小的顺序排列,我们可以采用如下方式来实现:

在这里需要和大家说明一下,在排序的语句中,ORDER BY关键字用于指定用于排序的列,而ASC表示查询结果按照升序进行排列,而DESC表示结果按照降序进行排列,在默认情况下,数据排序是按照升序进行排列的,也就是说即使我们不指定ASC或者DESC那么查询所得结果会按照升序进行排列,这就是排序命令各部分代表的含义。

针对查询结果排序,我们可能会遇到多列排序的情况,我们可以看下如下这个例子:

大家看,在这个例子中,我们在ORDER BY关键字后边指定了两个用于排序的列,紧跟在ORDER BY关键字后边的是用户名,它采用默认的升序排列方式,之后是一个用逗号隔开的另一个用于排序的列,这个列按照降序进行排列。在分析完这条查询语句之后,我们再来看一下具体的结果在展示的时候有什么特点,大家在这个显示的结果列表中可以看到,首先,查询的结果首先是按照用户名来显示的,而对于用户名为李四的相同的两列,大家可以看到编号为1的用户信息先展示出来,用户编号为的用户随后显示出来,这就是对于多个列作为排序列的时候应该如何理解。

针对上边这个例子,大家可以看出,我们的用户名存储的是中文,然后我们让它在显示的时候按照升序进行排列,想象中它应该按照汉语拼音字母的顺序,从a-z依次显示出来,但是这个结果并不是这样的?这是什么原因呢?这主要是因为我们创建数据库的时候,指定的编码格式是UTF-8格式的,所以在数据进行排序的时候它也会按照这个编码格式来进行排序,如果说我们想要让用户在排序的时候按照我们汉语拼音的顺序依次显示出来,那么可以尝试按照如下的方法来实现:

大家可以看到,这时候显示的结果就是按照汉语拼音的顺序降序排列的,也就是从z到a的顺序显示出来,其实这种方法就是将原先以UTF-8编码格式存储下来的数据转换为GBK形式,因为GBK是针对中文的的编码格式。

数据分组

在生活中我们常常会碰到这种情况,比如我们需要统计图书馆中各类图书的数目、或者统计下系统用男女用户的总数分别是多少、又或者我们需要统计班级中各科成绩的平均分是多少,针对这些情况,它们总是按照某种某种关系对所得结果进行归类,又或者说分组,针对这种情况在数据库中同样提供了对应的支持,就是数据分组,下边我们就来为大家介绍下MySQL中如何实现数据分组。

SELECT 列名列表 FROM 表名 GROUP BY 列名

如上所示就是分组排序的的实现方法,我们不妨在用户表中添加一个用户性别的列,然后来统计下用户表中男女用户一共有多少,如下就是我们模拟的数据:

在这里,我们用表示男,1表示女,用sex列存储用户性别,那么我们接下来就利用分组查询来统计下用户表中的男女用户分别有多少:

在这里我们利用了之前给大家介绍的聚合函数中的count(),来统计用户目的,这就是分组查询的功能。

分组过滤

之前我们为大家介绍数据表查询的时候,和大家说过使用WHERE可以过滤掉我们不需要的数据,这些需要和大家说明的是在SQL中提供了一个可以用于分组查询的过滤关键字HAVING,比如这里我们想要查询出总数超过3的用户出生日期:

大家可以看到,这里我们使用HAVING过滤掉了总数少于3的用户出生日期。到这里为止,很多人可能会感觉到奇怪,因为这个HAVING和WHERE似乎并没有多大的区别,这里我们不妨将上述案例中的HAVING以WHERE代替,然后再执行一下程序,看下所得结果是什么?

在使用WHERE之后,SQL语句执行的时候出现了错误,提示语法存在错误,这就是HAVING和WHERE的区别所在,也是分组查询中一个需要我们注意的地方。

注意

对于分组查询而言,它并不像排序的ORDER BY语句一样可以随意使用,它总是和聚合函数一起使用,而且在使用到分组排序的时候必须符合一定的逻辑,比如对于我们测试表中的user表来说,初学者会有这样一种误解,他想要以一条SQL语句查询出用户名、用户密码、用户编号这些信息,而且希望这些信息是按照性别分组显示的,对于这样一种需求,其实如果在学习或者测试的时候一旦产生这种想法就是错误的,因为我们查询所得结果都是水平的,针对这个需求而言,我们查询所得结果是用户表中所有的用户名、用户密码、用户编号这些信息,这样一个结果没有办法进行分组,那么在使用分组查询的时候有没有哪些技巧或者值得我们注意的地方呢?下边我们就针对这些内容为大家做相应的总结。

首先,我们必须牢记,使用到分组查询的语句,除了聚合函数外,其他查询的列都必须包括在GROUP BY语句中,请看如下这个案例:

其实理解这点并不困难,正如我们之前介绍的一样,如果说我们想让查询所得结果按照性别进行分组,但是还想同时显示出用户编号这个字段,那么这个字段在分组之后到底属于哪个呢?这和我们之前介绍的按照男女显示详细信息的情况是相同的。

第二点,就是如果查询的时候作为分组的列,它在存储的时候存储的值是NULL或者空字符的话,也会作为一个分组:

大家可以看到,在这个案例中,查询所得结果中第一行数据是NULL,第二行是空字符串,其他行是具体的生日时间,大家可以看到,在分组的时候将NULL、空字符串分别作为一个分组。

最后,我们需要为大家解决一个疑惑,就是在用到分组查询的时候,几乎总是会同时用到一个聚合函数,那么是否说明在所有的分组查询语句中必须用到聚合函数呢?答案是否定的,我们不妨将刚才的案例稍作调整:

PS:关于数据表简单查询相关的操作到这里为止已经为大家介绍完了,下一次我们将为大家介绍分组和排序查询相关的操作。如果您感觉这些内容对您的学习或者工作有所帮助的话,欢迎转发给您周围的同事或者朋友,感谢您的支持和帮助。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181217G06X1E00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券