SQL Server Group By语句

在本教程中,将学习如何使用SQL Server GROUP BY子句按一列或多列排列组中的行。

SQL Server GROUP BY子句简介

GROUP BY子句用于按分组排列查询的行。 这些分组由在GROUP BY子句中指定的列确定。

以下是GROUP BY子句的语法:

SELECT
    select_list
FROM
    table_name
GROUP BY
    column_name1,
    column_name2 ,...;

在此查询语法中,GROUP BY子句为列中的每个值组合生成一个组。

请考虑以下示例:

SELECT
    customer_id,
    YEAR (order_date) order_year
FROM
    sales.orders
WHERE
    customer_id IN (1, 2)
ORDER BY
    customer_id;

执行上面查询语句,得到以下结果:

在此示例中,检索了客户ID为1,列是:customer_idorder_date

从输出中可以清楚地看到,ID为1的客户在2016年下了一个订单,在2018年下了两个订单。ID为2的客户在2017年下了两个订单,在2018年下了一个订单。

在查询中添加一个GROUP BY子句来查看效果:

SELECT
    customer_id,
    YEAR (order_date) order_year
FROM
    sales.orders
WHERE
    customer_id IN (1, 2)
GROUP BY
    customer_id,
    YEAR (order_date)
ORDER BY
    customer_id;

执行上面查询语句,得到以下结果:

GROUP BY子句将前三行分为两组,接下来的三行分为另外两组,具有客户ID和订单年份的唯一组合。

从功能上讲,上面查询中的GROUP BY子句产生的结果与使用DISTINCT子句的以下查询的结果相同:

SELECT DISTINCT
    customer_id,
    YEAR (order_date) order_year
FROM
    sales.orders
WHERE
    customer_id IN (1, 2)
ORDER BY
    customer_id;

执行上面查询语句,得到以下结果:

1. GROUP BY子句和聚合函数

实际上,GROUP BY子句通常与聚合函数一起用于生成摘要报告。

聚合函数对组执行计算并返回每个组的唯一值。 例如,COUNT()函数返回每个组中的行数。 其他常用的聚合函数是:SUM()AVG()MIN()MAX()

GROUP BY子句将行排列成组,聚合函数返回每个组的摘要(总数量,最小值,最大值,平均值,总和等)。

例如,以下查询返回客户按年度下达的订单数:

SELECT
    customer_id,
    YEAR (order_date) order_year,
    COUNT (order_id) 订单数量
FROM
    sales.orders
WHERE
    customer_id IN (1, 2)
GROUP BY
    customer_id,
    YEAR (order_date)
ORDER BY
    customer_id;

执行上面查询语句,得到以下结果:

如果要引用GROUP BY子句中未列出的任何列或表达式,则必须使用该列作为聚合函数的输入。 否则,数据库系统将会提示错误,因为无法保证列或表达式将为每个组返回单个值。 例如,以下查询将失败:

SELECT
    customer_id,
    YEAR (order_date) order_year,
    order_status
FROM
    sales.orders
WHERE
    customer_id IN (1, 2)
GROUP BY
    customer_id,
    YEAR (order_date)
ORDER BY
    customer_id;

这是因为order_status列未在GROUP BY子句中。

2. 更多GROUP BY子句示例

下面再举几个例子来理解GROUP BY子句的工作原理。

2.1. 带有COUNT()函数示例的GROUP BY子句

以下查询返回每个城市的客户数量:

SELECT
    city,
    COUNT (customer_id) customer_count
FROM
    sales.customers
GROUP BY
    city
ORDER BY
    city;

执行上面查询语句,得到以下结果:

在此示例中,GROUP BY子句按城市将客户分组,COUNT函数返回每个城市的客户数。

同样,以下查询按州和城市返回客户数量。

SELECT
    city,
    state,
    COUNT (customer_id) customer_count
FROM
    sales.customers
GROUP BY
    state,
    city
ORDER BY
    city,
    state;

执行上面查询语句,得到以下结果:

2.2. GROUP BY子句带有MIN和MAX函数示例

以下声明返回所有型号年份为2018的最低和最高价产品:

SELECT
    brand_name,
    MIN (list_price) min_price,
    MAX (list_price) max_price
FROM
    production.products p
INNER JOIN production.brands b ON b.brand_id = p.brand_id
WHERE
    model_year = 2018
GROUP BY
    brand_name
ORDER BY
    brand_name;

执行上面查询语句,得到以下结果:

在此示例中,WHERE子句在GROUP BY子句之前。

2.3. 带有AVG()函数示例的GROUP BY子句

以下语句使用AVG()函数返回型号年份为2018年的所有产品的平均价格:

SELECT
    brand_name,
    AVG (list_price) avg_price
FROM
    production.products p
INNER JOIN production.brands b ON b.brand_id = p.brand_id
WHERE
    model_year = 2018
GROUP BY
    brand_name
ORDER BY
    brand_name;

执行上面查询语句,得到以下结果:

2.4. 带有SUM函数示例的GROUP BY子句

请参阅以下order_items表:

以下查询使用SUM()函数获取每个订单的净值:

SELECT
    order_id,
    SUM (
        quantity * list_price * (1 - discount)
    ) net_value
FROM
    sales.order_items
GROUP BY
    order_id;

执行上面查询语句,得到以下结果:


上一篇: SQL Server数据分组 下一篇: SQL Server子查询语句