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子句根据列或表达式的值将行分组到子组中。
