MySQL GROUP BY

时间:2019-11-20 08:52:05  来源:igfitidea点击:

简介:在本教程中,您将学习如何使用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在FROM,WHERE和SELECT子句之后以及HAVING,ORDER BY和LIMIT子句之前评估GROUP BY子句:

MySQL GROUP BY示例

让我们举一个使用GROUP BY子句的例子。

A)简单的MySQL GROUP BY示例

让我们看一下示例数据库中的订单表。

假设您要将订单状态的值分组为子组,请使用带有状态列的GROUP BY子句作为以下查询:

SELECT 
    status
FROM
    orders
GROUP BY status;

如您所见,GROUP BY子句返回状态值的唯一出现。
它的作用类似于DISTINCT运算符,如以下查询所示:

SELECT DISTINCT
    status
FROM
    orders;

B)使用具有聚合功能的MySQL GROUP BY

聚合函数使您可以计算一组行并返回单个值。
GROUP BY子句通常与聚合函数一起使用,以执行计算并为每个子组返回单个值。

例如,如果您想知道每种状态下的订单数量,则可以将COUNT函数与GROUP BY子句一起使用,如下所示:

SELECT 
    status, COUNT(*)
FROM
    orders
GROUP BY status;

请参阅以下订单和订单详细信息表。

要按状态获取所有订单的总金额,请将订单表与orderdetails表结合在一起,并使用SUM函数计算总金额。
请参阅以下查询:

SELECT 
    status, 
    SUM(quantityOrdered * priceEach) AS amount
FROM
    orders
INNER JOIN orderdetails 
    USING (orderNumber)
GROUP BY 
    status;

同样,以下查询返回订单号和每个订单的总金额。

SELECT 
    orderNumber,
    SUM(quantityOrdered * priceEach) AS total
FROM
    orderdetails
GROUP BY 
    orderNumber;

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函数从订单日期(orderDate)中提取年份数据。
我们仅在销售总额中包含具有发货状态的订单。
注意,出现在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 > 2003;

GROUP BY子句:MySQL与标准SQL

标准SQL不允许您在GROUP BY子句中使用别名,但是MySQL支持这一点。

例如,以下查询从订单日期中提取年份。
它首先使用year作为表达式YEAR(orderDate)的别名,然后在GROUP BY子句中使用year别名。
该查询在标准SQL中无效。

SELECT 
    YEAR(orderDate) AS year, 
    COUNT(orderNumber)
FROM
    orders
GROUP BY 
    year;

MySQL还允许您按升序或降序对组进行排序,而标准SQL则不允许。
默认顺序是升序。
例如,如果要按状态获取订单数并按降序对状态进行排序,则可以将GROUP BY子句与DESC一起使用,例如以下查询:

SELECT 
    status, 
    COUNT(*)
FROM
    orders
GROUP BY 
    status DESC;

请注意,我们在GROUP BY子句中使用了DESC对状态进行降序排序。
我们还可以在GROUP BY子句中明确指定ASC以按状态升序对组进行排序。

在本教程中,我们向您展示了如何使用MySQL GROUP BY子句根据列或表达式的值将行分组为子组。