SQL基础——聚合与排序(下)

简介: SQL基础——聚合与排序(下)

代码示例3.8 先计算数据行数再删除重复数据的结果

SELECT DISTINCT
    count( product_type ) 
FROM
    Product

执行结果


注意:想要计算值的种类时,可以在COUNT函数的参数中使用DISTINCT。

不仅限于COUNT函数,所有的聚合函数都可以使用DISTINCT。

对表进行分组 GROUP BY

使用GROUP BY子句可以像切蛋糕那样将表分割。通过使用聚合函数和GROUP BY子句,可以根据“商品种类”或者“登记日期”等将表分割后再进行汇总。

GROUP BY子句

语法3.1 使用GROUP BY子句进行汇总

SELECT
    <列名 1 >,
    <列名 2 >,
    <列名 3 >,
    …… 
FROM
    <表名> 
GROUP BY
    <列名 1 >,
    <列名 2 >,
    <列名 3 >,
    ……;

代码示例3.9 按照商品种类统计数据行数

select  product_type, count(*)
FROM Product
GROUP BY product_type

执行结果



GROUP BY子句就向切蛋糕那样将表进行了分组,分组之后在进行计算行数。在GROUP BY子句中指定的列成为聚合键或分组列。
注意:GROUP BY子句的书写位置也有严格要求,一定要写在FROM语句之后(如果有WHERE子句的话需要写在WHERE子句之后)

SQL子句的顺序不能改变,也不能互相替换。

聚合键中包含NULL的情况

将进货单价purchase_price作为聚合键对表进行切分。

代码示例3.10 按照进货单价统计数据行数

SELECT
    purchase_price,
    COUNT(*) 
FROM
    Product 
GROUP BY
    purchase_price;

执行结果


当聚合键中包含NULL时,也会将NULL作为一组特定的数据。

使用WHERE子句时GROUP BY的执行情况

语法3.2 使用WHERE子句和GROUP BY子句进行汇总处理

SELECT
    <列名 1 >,
    <列名 2 >,
    <列名 3 >,
    …… 
FROM
    <表名> 
WHERE
GROUP BY
    <列名 1 >,
    <列名 2 >,
    <列名 3 >,
    ……;

像这样使用WHERE子句进行汇总处理时,会先根据WHERE子句指定的条件进行过滤,然后再进行汇总处理。

代码示例3.15 同时使用WHERE子句和GROUP BY子句

SELECT
    purchase_price,
    COUNT(*) 
FROM
    Product 
WHERE
    product_type = '衣服' 
GROUP BY
    purchase_price;


执行结果


注意当GROUP BY 与WHERE并用时,SELECT语句的执行顺序

FROM→ WHERE→ GROUP BY→ SELECT

与聚合函数和GROUP BY子句有关的常见错误

常见错误① ——在SELECT子句中书写了多余的列

再使用聚合函数时,SELECT子句中只能存在以下三种元素。

常数、聚合函数、GROUP BY 子句中制定的列名(聚合键)
这里经常会出现的错误就是把聚合键以外的列名书写在SELECT子句中。


常见错误② ——在GROUP BY子句中写了列的别名

GROUP BY子句中使用列的别名会引发错误,原因是SQL语句在DBMS内部执行顺序造成的,由于SELECT子句在GROUP BY子句之后执行,在执行GROUP BY时,并不知道SELECT中的别名。

常见错误③ —— GROUP BY子句的结果能排序

GROUP BY 子句的结果都是无序的

常见错误④ ——在WHERE子句中使用聚合函数

只有SELECT子句和HAVING子句(以及ORDER BY子句)中能够使用聚合函数。

为聚合结果指定条件 HAVING

使用COUNT函数等对表中数据进行汇总操作时,为其指定条件的不是WHERE子句,而是HAVING

子句。

WHERE子句用来指定数据行的条件,HAVING子句用来指定分组的条件。

语法3.3 HAVING子句

SELECT
    <列名 1 >,
    <列名 2 >,
    <列名 3 >,
    …… 
FROM
    <表名> 
GROUP BY
    <列名 1 >,
    <列名 2 >,
    <列名 3 >,
    …… 
HAVING
    <分组结果对应的条件>

注意:HAVING子句必须写在GROUP BY子句之后,其在DBMS内部的执行顺序也排在GROUP BY子句之后。

代码示例 3.16 从按照商品种类进行分组的结果中,取出包含的数据行为2行的组

SELECT
    product_type,
    COUNT(*) 
FROM
    Product 
GROUP BY
    product_type
HAVING COUNT(*) = 2

执行结果



HAVING子句的构成要素

HAVING子句和包含GROUP BY子句时的SELECT子句一样,能够使用的要素有一定的限制,限制内容也是完全相同的。HAVING子句中能够使用的3中要素。
常数、聚合函数、GROUP BY 子句中制定的列名(聚合键)

相对于HAVING子句,更适合写在WHERE子句中的条件

有些条件既可以写在HAVING子句中,又可以写在WHERE子句中,这些条件就是聚合键所对应的条件。例如:

代码示例3.17 将条件写在HAVING子句中的情况

SELECT
    product_type,
    COUNT(*) 
FROM
    Product 
GROUP BY
    product_type
 HAVING product_type = '衣服';

执行结果


代码示例3.18 将条件写在WHERE子句中的情况

SELECT
    product_type,
    COUNT(*) 
FROM
    Product 
WHERE
    product_type = '衣服' 
GROUP BY
    product_type;

执行结果


注意:从结果上看,两种书写方式都没有问题,但是WHERE子句和HAVING子句的作用不同,HAVING子句用来指定组的条件,行所对应的条件还是应该写在WHRER子句当中。这样书写出来的SELECT语句不但可以分清两者各自的功能,理解起来也更加容易。

WHERE子句 = 指定行所对应的条件

HAVING子句 = 指定组所对应的条件

注意:WHERE子句和HAVING子句的执行速度

通过WHERE子句指定条件时,由于排序之前就对数据进行了过滤,因此能够减少排序的数据量。但HAVING子句是在排序之后才对数据进行分组的,因此与在WHERE子句中指定条件比起来,需要排序的数据量就会多得多此外,WHERE子句更具速度优势的另一个理由是,可以对WHERE子句指定条件所对应的列创建索引,这样也可以大幅提高处理速度。

对查询结果进行排序

使用ORDER BY子句对查询结果进行排序。在ORDER BY子句中列名的后面使用关键字ASC可以进行升序排序,使用DESC关键字可以进行降序排序。

通常,从表中选取数据时,如果没有特别指定顺序,最终排列顺序便无从得知。及时同一条SELECT语句,每次执行时排列顺序很磕碜发生变化。可以在SELECT语句末尾添加ORDER BY来明确指定排序。

语法3.4 ORDER BY 子句

SELECT
    <列名 1 >,
    <列名 2 >,
    <列名 3 >,
    …… 
FROM
    <表名> 
ORDER BY
    <排序基准列 1 >,
    <排序基准列 2 >,
    ……

代码示例3.19 按照销售单价由低到高(升序)进行排序

SELECT
    product_id,
    product_name,
    sale_price,
    purchase_price 
FROM
    Product 
ORDER BY
    sale_price;

执行结果




注意:不论何种情况,ORDER BY子句都需要写在SELECT语句的末尾。这是因为对数据行进行排序的操作必须在结果即将返回时执行。ORDER BY子句中书写的列名称为排序键。


注意:子句的书写顺序

SELECT子句 → 2. FROM子句 → 3. WHERE子句 → 4. GROUP BY子句 → 5. HAVING子句 → 6. ORDER BY子句

指定升序或降序

ORDER BY 默认升序(ASC),在列名后面使用DESC关键字表示降序

代码示例3.20 按照销售单价由高到低(降序)进行排序

SELECT
    product_id,
    product_name,
    sale_price,
    purchase_price 
FROM
    Product 
ORDER BY
    sale_price DESC;

执行结果



指定多个排序键

如果想要对该顺序的商品进行更细致的排序的话,就需要再添加一个排序键。

代码示例3.21 按照销售单价和商品编号的升序进行排序

SELECT
    product_id,
    product_name,
    sale_price,
    purchase_price 
FROM
    Product 
ORDER BY
    sale_price,
    product_id;

执行结果


可以在ORDER BY

子句中同时指定多个排序键了。规则是优先使用左侧的键,如果该列存在相同值的话,再接着参考右侧的键

NULL的顺序

排序键中包含NULL时,会在开头或末尾进行汇总

在排序键中使用显示用的别名

ORDER BY子句中却是允许使用别名的

代码示例3.22 ORDER BY子句中使用列的别名

SELECT
    product_id AS id,
    product_name,
    sale_price AS sp,
    purchase_price 
FROM
    Product 
ORDER BY
    sp,
    id;

执行结果


在GROUP BY子句中不能使用SELECT子句中定义的别名,但是在ORDER BY子句中却是允许使用别名的。

ORDER BY子句中可以使用的列

ORDER BY子句中也可以使用存在于表中、但并不包含在SELECT子句之中的列

代码示例3.23 SELECT子句中未包含的列也可以在ORDER BY子句中使用

SELECT
    product_name,
    sale_price,
    purchase_price 
FROM
    Product 
ORDER BY
    product_id;

执行结果


注意:除此之外,在ORDER BY子句中可以使用SELECT子句中未使用的列和聚合函数

如果博主的文章对您有所帮助,可以评论、点赞、收藏,支持一下博主!!!

目录
相关文章
|
5月前
|
SQL 数据库管理
第二章:基础查询与排序---SQL学习笔记
第二章:基础查询与排序---SQL学习笔记
76 0
|
5月前
|
SQL 存储
SQL组内排序
为什么要用ORDER BY来做,因为是这样的,由于采用的多线程,各个线程触发时间十分相近,但是我们需要对每一个项目进行分组,所以在此处,我们做了一个唯一标识IDENTIFICATION,每个项目每次执行时记录的6条日志里都会存储这个唯一标识。
|
2月前
|
SQL 流计算
Flink SQL 在快手实践问题之Window TVF改进窗口聚合功能如何解决
Flink SQL 在快手实践问题之Window TVF改进窗口聚合功能如何解决
18 1
|
3月前
|
分布式计算 BI MaxCompute
SQL 能力问题之输出聚合的维度列的名称,如何解决
SQL 能力问题之输出聚合的维度列的名称,如何解决
|
4月前
|
SQL 关系型数据库 MySQL
MySQL数据库——SQL(3)-DQL(基本查询、条件查询、聚合函数、分组查询、排序查询、分页查询、案例练习)
MySQL数据库——SQL(3)-DQL(基本查询、条件查询、聚合函数、分组查询、排序查询、分页查询、案例练习)
51 0
|
5月前
|
分布式计算 资源调度 Hadoop
Flink报错问题之Sql往kafka表写聚合数据报错如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
|
5月前
|
SQL
SQL语句两个字段或多个字段同时order by 排序
SQL语句两个字段或多个字段同时order by 排序
832 0
|
5月前
|
SQL 数据库管理
SQL基础题----基本的SELECT语句、order by排序
SQL基础题----基本的SELECT语句 ambiguous 模糊
208 1
|
5月前
|
SQL 人工智能 运维
数据库基础入门 — SQL排序与分页
数据库基础入门 — SQL排序与分页
48 0
|
5月前
|
SQL 数据采集 分布式计算
Spark SQL中的聚合与窗口函数
Spark SQL中的聚合与窗口函数
下一篇
无影云桌面