在本教學中,將學習如何使用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_id
和order_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;
執行上面查詢語句,得到以下結果: