MySQL GROUP BY
简介:在本教程中,您将学习如何使用MySQL
GROUP BY
根据列或表达式的值将行分组到子组中。
MySQL GROUP BY子句简介
GROUP BY
子句按行或表达式的值将一组行分组为一组摘要行。GROUP BY
子句为每个组返回一行。换句话说,它减少了结果集中的行数。
GROUP BY
子句经常使用与聚合函数,例如SUM
,AVG
,MAX
,MIN
,和COUNT
。SELECT
子句中显示的聚合函数提供有关每个组的信息。
GROUP BY
子句是SELECT
语句的可选子句。以下说明了GROUP BY
子句语法:
SELECT c1, c2,..., cn, aggregate_function(ci) FROM table WHERE where_conditions GROUP BY c1 , c2,...,cn;
GROUP BY
必须出现在FROM
和WHERE
之后。继GROUP BY
关键字是要作为标准组行用逗号分隔的列或表达式的列表。
MySQL GROUP BY 实例
我们来看一些使用GROUP BY
子句的例子。
A)简单的MySQL GROUP BY示例
我们来看看示例数据库中的orders
表。
+----------------+ | orders | +----------------+ | orderNumber | | orderDate | | requiredDate | | shippedDate | | status | | comments | | customerNumber | +----------------+ 7 rows in set (0.01 sec)假设您要将订单状态的值分组到子组中,请使用
GROUP BY
带有status
列的子句作为以下查询:
SELECT status FROM orders GROUP BY status;运行结果:
+------------+ | status | +------------+ | Cancelled | | Disputed | | In Process | | On Hold | | Resolved | | Shipped | +------------+ 6 rows in set (0.00 sec)如您所见,
GROUP BY
子句返回唯一status
值的值。它的工作方式与DISTINCT
运算符类似,如下面的查询所示:
SELECT DISTINCT status FROM orders;
B)使用MySQL GROUP BY 和聚合函数
聚合函数允许您执行一组行的计算,并返回一个值。GROUP BY
子句通常与聚合函数一起使用以执行计算并为每个子组返回单个值。
例如,如果您想知道每个状态中的订单数,可以使用带有GROUP BY
子句的COUNT
函数,如下所示:
SELECT status, COUNT(*) FROM orders GROUP BY status;运行结果:
+------------+----------+ | status | COUNT(*) | +------------+----------+ | Cancelled | 6 | | Disputed | 3 | | In Process | 6 | | On Hold | 4 | | Resolved | 4 | | Shipped | 303 | +------------+----------+ 6 rows in set (0.00 sec)请参阅以下内容
orders
和 orderdetails
表格。
+-----------------+ | orderdetails | +-----------------+ | orderNumber | | productCode | | quantityOrdered | | priceEach | | orderLineNumber | +-----------------+ 5 rows in set (0.01 sec)要按状态得到的所有订单的总金额,使用INNSER JOIN 关联
orders
表与orderdetails
表和使用SUM
功能来计算总量。请参阅以下查询:
SELECT status, SUM(quantityOrdered * priceEach) AS amount FROM orders INNER JOIN orderdetails USING (orderNumber) GROUP BY status;运行结果:
+------------+------------+ | status | amount | +------------+------------+ | Cancelled | 238854.18 | | Disputed | 61158.78 | | In Process | 135271.52 | | On Hold | 169575.61 | | Resolved | 134235.88 | | Shipped | 8865094.64 | +------------+------------+ 6 rows in set (0.00 sec)同样,以下查询返回订单号和每个订单的总金额。
SELECT orderNumber, SUM(quantityOrdered * priceEach) AS total FROM orderdetails GROUP BY orderNumber;运行结果:
+-------------+----------+ | orderNumber | total | +-------------+----------+ | 10100 | 10223.83 | | 10101 | 10549.01 | | 10102 | 5494.78 | | 10103 | 50218.95 | | 10104 | 40206.20 | | 10105 | 53959.21 | | 10106 | 52151.81 | ...
C)MySQL GROUP BY 带有表达式实例
除了列之外,您还可以按表达式对行进行分组。以下查询获取每年的总销售额。SELECT YEAR(orderDate) AS year, SUM(quantityOrdered * priceEach) AS total FROM orders INNER JOIN orderdetails USING (orderNumber) WHERE status = 'Shipped' GROUP BY YEAR(orderDate);运行结果:
+------+------------+ | year | total | +------+------------+ | 2013 | 3223095.80 | | 2014 | 4300602.99 | | 2015 | 1341395.85 | +------+------------+ 3 rows in set (0.01 sec)在此示例中,我们使用
YEAR
函数从订单日期(orderDate
)中提取年份数据。我们仅包含shipped
在总销售额中具有状态的订单。请注意,SELECT
子句中出现的表达式必须与GROUP BY
子句中的表达式相同。
D)MySQL GROUP BY和HAVING子句实例
要过滤GROUP BY
子句返回的组,请使用 HAVING
子句。以下查询使用HAVING
子句选择2003年后的年份总销售额。
SELECT YEAR(orderDate) AS year, SUM(quantityOrdered * priceEach) AS total FROM orders INNER JOIN orderdetails USING (orderNumber) WHERE status = 'Shipped' GROUP BY year HAVING year > 2013;运行结果:
+------+------------+ | year | total | +------+------------+ | 2014 | 4300602.99 | | 2015 | 1341395.85 | +------+------------+ 2 rows in set (0.00 sec)
GROUP BY子句:MySQL与标准SQL
标准SQL不允许您在
例如,以下查询从订单日期中提取年份。它首先GROUP BY
子句中使用别名,但MySQL支持此功能。
year
用作表达式的别名,YEAR(orderDate)
然后year
在GROUP BY
子句中使用别名。此查询在标准SQL中无效。
SELECT YEAR(orderDate) AS year, COUNT(orderNumber) FROM orders GROUP BY year;运行结果:
+------+--------------------+ | year | COUNT(orderNumber) | +------+--------------------+ | 2013 | 111 | | 2014 | 151 | | 2015 | 64 | +------+--------------------+ 3 rows in set (0.00 sec)MySQL还允许按升序或降序对组进行排序,而标准SQL则不然。默认顺序为升序。例如,如果要按状态获取订单数并按降序对状态进行排序,则可以使用
GROUP BY
子句DESC
作为以下查询:
SELECT status, COUNT(*) FROM orders GROUP BY status DESC;运行结果:
+------------+----------+ | status | COUNT(*) | +------------+----------+ | Shipped | 303 | | Resolved | 4 | | On Hold | 4 | | In Process | 6 | | Disputed | 3 | | Cancelled | 6 | +------------+----------+ 6 rows in set (0.01 sec)
注意:在
在本教程中,我们向您展示了如何使用MySQL GROUP BY
子句中使用DESC
对字段 status
按降序排序。我们还可以在GROUP BY
子句中明确指定 ASC
按状态按升序对组进行排序。
GROUP BY
子句根据列或表达式的值将行分组到子组中。