MySQL 中 Group By 的用法

Group By 是一种 SQL 查询语句,常用于根据一个或多个列对查询结果进行分组。在 Group By 子句中指定的列将成为分组依据,而在 Select 子句中指定的列必须是聚合函数(例如 SUM、AVG、COUNT 等)或分组列。

Group By 的语法如下:

SELECT column_name(s) FROM table_name WHERE condition GROUP BY column_name(s);

其中,column_name 是需要返回的列名,table_name 是需要查询的表名,condition 是查询条件。使用 Group By 时,需要注意以下几点:

  • 如果在 Select 子句中没有指定聚合函数,则必须将该列也包含在 Group By 子句中。
  • 在 Group By 中指定的列可以是表达式或函数,但在 Select 子句中必须使用别名来引用这些列。

假设我们有一个存储用户订单信息的表 orders,其中包含了订单号、客户 ID、订单日期和订单金额四个字段。我们现在需要按照客户 ID 对所有订单进行分组,并计算每个客户的订单数和总金额。可以使用 Group By 如下:

SELECT customer_id, COUNT(order_number) AS order_count, SUM(order_amount) AS total_amount FROM orders GROUP BY customer_id;

在上面的示例中,我们使用 GROUP BY 子句指定了客户 ID 列作为分组依据,并在 Select 子句中使用了 COUNT 和 SUM 聚合函数来计算每个客户的订单数和总金额。

Group By 例子

以下是用于演示 Group By 的 SQL 语句以及相应的结果:

SELECT category, SUM(price) AS total_price FROM products GROUP BY category;

categorytotal_price
Book150
Pen50
Pencil20

在上面的示例中,我们使用 GROUP BY 子句指定了产品类别列作为分组依据,并使用了 SUM 聚合函数来计算每个类别的总价值。

相关的方法

除了 Group By 之外,还有一些与 Group By 用法相近的方法可以用于对查询结果进行聚合和分组。其中包括以下几种:

Having

Having 是一个可选的子句,在 Group By 后面使用,用于过滤分组后的结果。通常用于筛选特定的分组,或者根据聚合函数计算的结果进行过滤。

SELECT column_name(s) FROM table_name WHERE condition GROUP BY column_name(s) HAVING condition;

在上面的语法中,column_name 是需要返回的列名,table_name 是需要查询的表名,condition 是查询条件。在使用 Having 时需要注意以下几点:

  • Having 子句中的条件是基于聚合函数计算的结果进行过滤的。
  • 如果在 Select 子句中没有使用聚合函数,则必须在 Group By 子句中包含该列。
  • 如果条件中只涉及到一个聚合函数,可以使用 WHERE 子句代替 Having 子句。

假设我们有一个存储学生成绩信息的表 scores,其中包含了学生姓名、科目和分数三个字段。我们现在需要查询分数在 60 分以上的每个学生在每个科目上的平均分数。可以使用 Having 如下:

SELECT student_name, subject, AVG(score) AS average_score FROM scores GROUP BY student_name, subject HAVING AVG(score) > 60;

在上面的示例中,我们首先使用 Group By 对学生姓名和科目进行分组,然后使用 Having 条件过滤了分数平均值在 60 分以上的结果。

Rollup

Rollup 是一种可选的子句,在 Group By 子句后面使用,用于生成分组汇总行。通过使用 Rollup,可以将多组数据汇总为单组数据,并生成具有层次结构的报告。

SELECT column_name(s) FROM table_name WHERE condition GROUP BY column_name(s) WITH ROLLUP;

在上面的语法中,column_name 是需要返回的列名,table_name 是需要查询的表名,condition 是查询条件。使用 Rollup 时需要注意以下几点:

  • Rollup 子句可以用于生成多级汇总报告。
  • 对于每个分组列,Rollup 将生成一个子总计行。
  • 如果在 Group By 子句中指定了多个分组列,则 Rollup 将生成每个分组列的所有可能组合情况的子总计行。

假设我们有一个存储销售订单信息的表 orders,其中包含了订单日期、客户 ID 和订单金额三个字段。我们现在需要对订单日期和客户 ID 进行分组,并按照订单日期、客户 ID 和总金额生成汇总报告。可以使用 Rollup 如下:

SELECT order_date, customer_id, SUM(order_amount) AS total_amount FROM orders GROUP BY order_date, customer_id WITH ROLLUP;

在上面的示例中,我们使用 Group By 按照订单日期和客户 ID 进行分组,并在 Select 子句中使用了 SUM 聚合函数来计算每个客户在每个日期的总销售额。接着,使用 Rollup 生成了按照日期、客户 ID 和总金额的汇总报告。

结论

Group By 是一种常用的 SQL 查询语句,用于根据一个或多个列对查询结果进行分组。除了 Group By 之外,还有一些与 Group By 用法相近的方法可以用于对查询结果进行聚合和分组,例如 Having 和 Rollup。在使用这些方法时,需要根据实际需求选择合适的语句,以达到最佳的查询效果。

示例代码

以下是用于演示 Group By、Having 和 Rollup 的 SQL 语句以及相应的结果:

Group By 示例

SELECT customer_id, COUNT(order_number) AS order_count, SUM(order_amount) AS total_amount FROM orders GROUP BY customer_id;

customer_idorder_counttotal_amount
12400
21200
31100

Having 示例

SELECT student_name, subject, AVG(score) AS average_score FROM scores GROUP BY student_name, subject HAVING AVG(score) > 60;

student_namesubjectaverage_score
AliceMath70.5
BobEnglish70
LindaScience80
TomMath65
TomScience70

Rollup 示例

SELECT order_date, customer_id, SUM(order_amount) AS total_amount FROM orders GROUP BY order_date, customer_id WITH ROLLUP;

order_datecustomer_idtotal_amount
2022-01-011200
2022-01-012100
2022-01-01NULL300
2022-01-021200
2022-01-02NULL200
NULLNULL500