SQL Server基础知识:使用SQL GROUP BY子句

SQL Server 的 T-SQL 查询语言具有丰富的数据检索选项。这包括查询 SQL 数据库的能力,以及提供求和函数、计数聚合函数和分组列。SQL GROUP BY 子句可以利用所有这些功能。在本文中,我将向您展示 GROUP BY 子句如何单独使用或与其中一个聚合函数结合使用来执行基于分组的计算。

SQL GROUP BY 子句如何工作?

SQL GROUP BY 子句与SELECT 语句一起使用,将数据排列成相同数据的组。它在 SELECT 语句中的 WHERE 子句之后。

广告

这个子句通常与 SUM、COUNT、AVG、MAX 或 MIN 等聚合函数一起使用,这些函数允许您对分组数据进行计算。您可以按不同的列类型对数据进行分组,包括产品 ID、日期或描述等字符。

基本的 GROUP BY 语法非常简单:

SELECT column1, aggregate_function(column2)
FROM table_name
GROUP BY column1;

這裡,您可以看到GROUP BY子句與基本的SELECT語句一起使用。SELECT語句檢索兩列,第二列使用了聚合函數。

使用聚合函數並不是技術上必需的,但它是GROUP BY子句的一個非常常見的附屬物。分組將在第一列中包含的數據上執行。

廣告

讓我們深入探討並看看GROUP BY子句的實際應用。

使用SQL GROUP BY與SELECT語句

首先,讓我們只看看如何使用SQL GROUP BY子句與簡單的SELECT語句,而不添加聚合函數。以下清單從SalesLT.SalesOrderDetail表中檢索並分組“Product ID”列,在AdventureWorksLT2019樣本數據庫中。

USE AdventureWorksLT2019;

SELECT ProductID FROM SalesLT.SalesOrderDetail
  GROUP BY ProductID;

這基本上返回了已訂購的所有ProductIDs的列表,正如您在下圖中所看到的。

We get a list of all of the ProductIDs that have been ordered (Image credit: Petri/Michael Otey)

使用SQL GROUP BY與聚合函數

更常見的是使用SQL的GROUP BY子句與其中一個聚合函數,該函數可以給出您已分組在一起的所有列的計數、總計、平均值或摘要。以下語句使用GROUP BY與AdventureWorksLT2019數據庫中的SalesLT.Product表,以查找每個產品類別中的產品總數:

廣告

USE AdventureWorksLT2019;

SELECT ProductCategoryID, COUNT(*) AS TotalProducts
  FROM SalesLT.Product
   GROUP BY ProductCategoryID;

在這個例子中,SELECT語句從SalesLT.Product表返回’ProductCategoryID’列,並使用COUNT(*)聚合函數計算每個類別中的產品數量。在這裡,GROUP BY子句按’ProductCategoryID’對結果進行分組,而SELECT COUNT函數計算每個產品類別中的產品總數。COUNT(*)函數的結果使用別名’TotalProducts’。

此查詢的結果顯示在以下圖中。此輸出顯示每個產品類別中的產品總數,這是使用GROUP BY子句計算的。摘要信息由COUNT(*)聚合函數返回。

Using SQL GROUP BY with aggregate functions (Image credit: Petri/Michael Otey)

使用SQL GROUP BY與多列

SQL的GROUP BY函數不僅限於與單個列一起工作。它還可以在同一查詢中同時與多個列一起使用。

讓我們來看一個在 AdventureWorksLT2019 資料庫中使用 SalesLT.Product 表的 GROUP BY 子句的例子,並選擇兩個欄位。以下查詢顯示如何檢索每個產品類別和產品型號的總產品數量。

USE AdventureWorksLT2019;

SELECT ProductCategoryID, ProductModelID, COUNT(*) AS TotalProducts
  FROM SalesLT.Product
  GROUP BY ProductCategoryID, ProductModelID;

在這裡,我們都檢索了 ‘ProductCategoryID’ 和 ‘ProductModelID’ 欄位,並使用 COUNT(*) 聚合函數來計算每個產品類別和子類別中的產品數量。在這個例子中,GROUP BY 子句將 ‘ProductCategoryID’ 和 ‘ProductModelID’ 欄位的結果分組。這樣就基於這兩個不同的欄位創建了兩個不同的群組。

您可以在下圖中看到此查詢的結果。這些結果顯示了產品和產品型號的總數,並使用名為 TotalProducts 的欄位別名檢索總計數。

Using SQL GROUP BY with multiple columns (Image credit: Petri/Michael Otey)

使用 SQL GROUP BY 與 HAVING 子句

GROUP BY 子句的另一個常見用法是與 HAVING 子句結合使用。實際上,您可以使用 GROUP BY 子句與 HAVING 子句來根據 HAVING 子句應用到數據分組的條件來篩選查詢的結果。條件可以應用於常規數據類型列或聚合函數。

讓我們看一個使用 SQL GROUP BY 子句和 HAVING 子句的示例,並與 AdventureWorksLT2019 資料庫一起使用。此示例顯示在 SalesLT.SalesOrderHeader 表中有訂單總金額大於 $2000 的客戶。在這裡,GROUP BY 子句用於按客戶分組訂單,然後 HAVING 子句基於總訂單金額篩選客戶。

USE AdventureWorksLT2019;

SELECT  c.CustomerID, c.FirstName, c.LastName, SUM(soh.TotalDue) AS TotalOrderAmount
  FROM SalesLT.Customer c
 JOIN SalesLT.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID
  GROUP BY c.CustomerID, c.FirstName, c.LastName
 HAVING SUM(soh.TotalDue) > 2000;
  • 在此代碼清單中,SalesLT.Customer 表與 SalesLT.SalesOrderHeader 表根據 ‘CustomerID’ 列進行連接。
  • SELECT 列擷取 ‘CustomerID’、’FirstName’、’LastName’ 和 ‘TotalOrderAmount’。
  • GROUP BY 子句用於按客戶分組結果。
  • SUM() 聚合函數計算每個客戶的總訂單金額。
  • HAVING 子句將分組結果篩選為只選擇總訂單金額大於 $2000 的客戶。

您可以在以下圖中看到此代碼清單的結果:

Using SQL GROUP BY with the HAVING clause (Image credit: Petri/Michael Otey)

使用 SQL GROUP BY 與 ORDER BY 子句

您也可以使用 SQL 的 GROUP BY 子句和 ORDER BY 子句来按一个或多个列对结果集进行排序。以下示例使用 AdventureWorksLT2019 数据库。为了说明如何使用 ORDER BY 子句与 GROUP BY 子句,您可以简单地采用先前的示例代码,并添加 ORDER BY 子句以按降序排序结果,显示最大的订单金额。

USE AdventureWorksLT2019;

SELECT  c.CustomerID, c.FirstName, c.LastName, SUM(soh.TotalDue) AS TotalOrderAmount
  FROM SalesLT.Customer c
   JOIN SalesLT.SalesOrderHeader soh ON c.CustomerID = soh.CustomerID
  GROUP BY c.CustomerID, c.FirstName, c.LastName
   HAVING SUM(soh.TotalDue) > 2000
   ORDER BY TotalOrderAmount DESC;

您可以在以下图中看到结果。这些结果显示了订单金额超过 $2000 的客户列表,按降序排列,最大订单的客户排在前面。

Using SQL GROUP BY with the ORDER BY clause (Image credit: Petri/Michael Otey)

正如您所见,SQL 的 GROUP BY 子句可以做很多事情。我向您展示了如何使用多个列的 GROUP BY 子句,以及如何添加 HAVING 和 ORDER BY 子句来过滤和排序结果。

和往常一样,随时提出关于 SQL GROUP BY 子句的任何问题。如果您想了解更多关于 SQL Server 的信息,请随时查看我 SQL Server 基础系列 中的先前文章。

Source:
https://petri.com/sql-group-by/