SQL复习02 | 聚合与排序

1. 对表进行聚合查询

聚合,就是将多行汇总为一行

在 SQL 中,聚合函数是指一类用于对数据进行汇总计算的函数,例如计算总和、平均值、最大值、最小值、数量等等。

聚合函数通常与 GROUP BY 子句一起使用,用于对分组后的数据进行聚合计算。

在 SQL 中,常见的聚合函数包括:

  • COUNT:用于计算指定列中行的数量。
  • SUM:用于计算指定列中所有数值的总和。
  • AVG:用于计算指定列中所有数值的平均值。
  • MAX:用于查找指定列中最大的数值。
  • MIN:用于查找指定列中最小的数值。

使用 COUNT 函数的参数不同,计算的结果也会发生变化,如:

  1. COUNT(*)会得到包含NULL的数据行数
  2. COUNT(<列名>)会得到NULL之外的数据行数

注意:

  • 所有的聚合函数(COUNT(*)例外)会将NULL排除在外
  • MAX/MIN函数几乎适用于所有数据类型(如整型、浮点型、日期型等)的列,SUM/AVG函数只适用于数值类型的列

使用聚合函数删除重复行

  1. 想要计算值的种类时,可以在COUNT函数的参数中使用DISTINCT
    --这时DISTINCT必须写在括号中,因为必须要在计算行数之前删除列中的重复数据
    SELECT COUNT(DISTINCT <列名>) FROM <表名>;
    
  2. 在聚合函数的参数中使用DISTINCT,可以删除重复数据行

2. 对表进行分组(GROUP BY)

先分组,再汇总

SELECT <列名1>, <列名2>, <列名3>
	FROM <表名>
GROUP BY <列名1>, <列名2>, <列名3>;
  • GROUP BY子句中指定的列称为聚合键或者分组列
  • GROUP BY就像是切分表的一把刀
  • GROUP BY一定要写在FROM语句之后(如果有WHERE子句的话需要写在WHERE子句之后)
  • 当聚合键中包含NULL时,在结果中会以**“不确定”行(空行)**的形式表现出来

GROUP BYWHERE并用时SELECT语句的执行顺序:FROM —> WHERE —> GROUP BY —> SELECT

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

  1. 在SELECT子句中不能出现聚合键之外的列名,是由于会出现聚合键和列名不是一一对应的情况
  2. 在GROUP BY子句中不能使用SELECT子句中定义的别名,是由于SQL在DBMS内部的执行顺序造成的
  3. GROUP BY子句结果的显示是无序的
  4. 在WHERE子句中不能使用聚合函数,只有SELECT、HAVING、ORDER BY子句中能够使用聚合函数

3. 为聚合结果指定条件

对集合指定条件需要使用HAVING子句

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

使用HAVING子句时SELECT语句顺序:SELECT —> FROM —> WHERE —> GROUP BY —> HAVING

  • HAVING子句要写在GROUP BY子句之后

HAVING子句能够使用的3种要素:

  1. 常数
  2. 聚合函数
  3. GROUP BY子句中指定的列名(聚合键)

聚合键(GROUP BY 字段)所对应的条件应该写在HAVING中,原因如下:

  1. 根本原因时WHERE子句和HAVING子句的作用不同。其中WHERE 子句是在对数据进行分组之前对行进行过滤的条件,而 HAVING 子句是在对数据进行分组之后对分组进行过滤的条件

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

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

  2. WHERE子句的执行速度比HAVING子句执行速度更快。

    • WHERE 子句过滤行时,是在从表中读取数据时进行的。因此,可以在查询之前使用 WHERE 子句对数据进行快速过滤,只返回满足条件的行,这样可以减少读取的行数,从而提高查询的效率
    • HAVING 子句过滤分组时,是在对 GROUP BY 后的结果进行计算时进行的。因此,必须等到分组之后才能执行 HAVING 子句,这可能需要进行额外的计算,从而降低查询的效率。
    • WHERE 子句可以使用索引,从而加快查询的速度。索引可以提高 WHERE 子句的查询效率,因为它可以帮助数据库引擎快速查找满足 WHERE 子句条件的行。

4. 对查询结果进行排序

SELECT <列名1>, <列名2>, <列名3>
FROM <表名>
ORDER BY <排序基准列1>, <排序基准列2>
  • ORDER BY都需要写在SELECT子句的末尾
  • 子句的书写顺序:SELECT —> FROM —> WHERE —> GROUP BY —> HAVING —> ORDER BY
  • 子句的执行顺序:FROM —> WHERE —> GROUP BY —> HAVING —> SELECT —> ORDER BY,所以ORDER BY子句中可以使用SELECT子句中定义的别名
  • ORDER BY子句中书写的列名称为排序键
  • ORDER BY子句中可以使用SELECT子句中未使用的列和聚合函数
  • ORDER BY子句中不要使用列编号,同时在 SQL 查询中使用列编号(即列的顺序号)可能会导致以下问题:
    1. 可读性较差:使用列编号时,查询语句可能难以理解和维护,尤其是对于较长和复杂的查询语句。使用列名或别名可以提高查询语句的可读性和可维护性。
    2. 容易出错:如果查询中的列顺序发生变化,列编号也会随之改变,这可能会导致错误的排序或分组,而这种错误可能很难被发现和修复。使用列名或别名可以避免这种问题。
    3. 可移植性差:不同的数据库管理系统可能使用不同的列编号规则,因此查询可能无法在不同的 DBMS 中正确执行。使用列名或别名可以提高查询语句的可移植性。

ASC(ascendent)和DESC(descendent)关键字

  • ASC:升序,从低到高排列(默认)
  • DESC:降序,从高到低排列
  • 支持多个排序键,优先使用左侧的键,再参考右侧的键
  • 若排序键中包含NULL时,会在开头或末尾进行汇总,以下是一些 DBMS 中可以指定 NULL 在开头或末尾显示的方法:
    1. MySQL: 可以使用 ORDER BY 子句的 ASC 或 DESC 关键字来指定 NULL 值在升序或降序排序中的位置。例如,ORDER BY column_name ASC NULLS FIRST,将 NULL 值显示在排序结果的开头,ORDER BY column_name DESC NULLS LAST,将 NULL 值显示在排序结果的末尾。
    2. PostgreSQL: 可以使用 ORDER BY 子句的 ASC 或 DESC 关键字来指定 NULL 值在升序或降序排序中的位置。例如,ORDER BY column_name ASC NULLS FIRST,将 NULL 值显示在排序结果的开头,ORDER BY column_name DESC NULLS LAST,将 NULL 值显示在排序结果的末尾。
    3. Oracle: 可以使用 ORDER BY 子句的 ASC 或 DESC 关键字来指定 NULL 值在升序或降序排序中的位置。例如,ORDER BY column_name ASC NULLS FIRST,将 NULL 值显示在排序结果的开头,ORDER BY column_name DESC NULLS LAST,将 NULL 值显示在排序结果的末尾。
    4. Microsoft SQL Server: 可以使用 ORDER BY 子句的 ASC 或 DESC 关键字来指定 NULL 值在升序或降序排序中的位置。例如,ORDER BY column_name ASC NULLS FIRST,将 NULL 值显示在排序结果的开头,ORDER BY column_name DESC NULLS LAST,将 NULL 值显示在排序结果的末尾。

你可能感兴趣的:(#,SQL基础,sql,聚合,排序)