1. 程式人生 > >四巨頭第七周作業翻譯

四巨頭第七周作業翻譯

tle pla 使用 子句 int 一行 order by 應用程序 多維數據

系列

這篇文章是階梯系列的一部分:通向T—SQL DML的階梯。

通過使用SQL Server的Transact-SQL (T-SQL)方言,這個階梯將為您提供如何使用SQL Server表數據的基本理解。DML是數據處理語言,是處理數據的語言的方面。它包括語句選擇、插入、更新和刪除。這個階梯將提供一些SQL語言的歷史和一些關於集合理論的一般概念。每個級別都將建立在之前的級別上,所以當你完成時,你將很好地理解如何從SQL Server中選擇和修改數據。

在階梯6中,我向你展示了如何使用ORDER BY子句對數據進行排序。這使你可以根據單個或多個列對詳細的記錄進行排序。如果你希望在特定記錄中查看數據,那麽詳細的數據就非常好,但是有時候你需要將詳細的數據匯總到匯總值中。你可以使用GROUP BY子句完成的數據來總結。

有兩種類型的GROUP BY子句。一種被稱為簡單的GROUP BY子句,另一種則提供了簡單的概括,稱為一般 GROUP BY子句。這兩種類型的主要區別是簡單的GROUP BY子句只包含GROUP BY子句,而一般 GROUP BY子句包含其他操作符,如匯總和多維數據集。

在本文中,我將介紹如何使用簡單的group BY子句對數據進行分組。在後續的一篇文章中,我將要討論更復雜的一般 GROUP BY子句。

簡單的GROUP BY子句

使用簡單GROUP BY子句可以根據單個列、多個列或表達式聚合數據。根據GROUP BY子句中指定的列和表達式,只對每個惟一的值返回一個匯總行。當SQL Server通過子句處理一個組時,它通過惟一的列或表達式值對詳細記錄進行分組,然後根據選擇列表中包含的聚合函數對每個集合進行總結。

為了更好地理解如何使用GROUP BY子句,讓我們假設你有一個表,其中包含了不同的商店的詳細銷售信息,你希望通過存儲來總結總銷售額。你可以使用GROUP BY子句來聚合每個商店的總銷售額。在本例中,要分組的唯一列是存儲名稱,而要聚合的列是銷售額。你的結果將顯示每個惟一的存儲名的其中一行,並且每個存儲的行將包含該存儲內容的銷售額之和。

通過查詢,SQL Server在哪些列可以包含在一個組的選擇列表中有一些限制。查詢組的選擇列表中指定的每一列都需要歸入以下類別之一:

l 在GROUP BY子句中指定的列

l 在GROUP BY子句中指定的表達式

l 從聚合函數返回的值

如果一個列不屬於這些類別之一,那麽當你試圖通過查詢並運行你的組時,你就會得到一個錯誤的信息。註意,GROUP BY子句中包含的列或表達式不需要出現在select列表中。

讓我通過幾個示例來幫助演示如何使用簡單GROUP BY子句來獲得匯總值。

簡單的GROUP BY子句的示例

為了演示如何使用一個簡單的GROUP BY子句,我構建了一些示例數據,並提供了一個腳本來創建我的示例數據,這樣我們就可以運行本文提供的示例代碼。使用清單1中的腳本構建並填充示例表。

SET NOCOUNT ON;

-- Create Sales Table

CREATE TABLE dbo.SalesTransaction

(Id INT IDENTITY PRIMARY KEY

,CustomerName VARCHAR(65)

,TotalSalesAmount money

,SalesTypeDesc VARCHAR(200)

,SalesDateTime DATETIME

,StoreName VARCHAR(100));

-- Add data to Sales Table

INSERT INTO dbo.SalesTransaction

VALUES (‘John Smith‘, 124.23,‘Software‘,‘09/22/2011 11:51:12 AM‘,‘The Software Outlet‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Jack Thomas‘, 29.56,‘Computer Supplies‘,‘09/23/2011 10:21:49 AM‘,‘The Software Outlet‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Sue Hunter‘, 89.45,‘Computer Supplies‘,‘09/23/2011 2:51:56 AM‘,‘The Software Outlet‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Karla Johnson‘, 759.12,‘Software‘,‘09/23/2011 2:54:37 PM‘,‘The Software Outlet‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Gary Clark‘, 81.51,‘Software‘,‘09/22/2011 11:08:52 AM‘,‘Discount Software‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Scott Crochet‘, 12345.78,‘Computer Supplies‘,‘09/23/2011 3:12:37 PM‘,‘Discount Software‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Sheri Holtz‘, 12.34,‘Software‘,‘09/23/2011 10:51:42 AM‘,‘Discount Software‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Mary Lee‘, 101.34,‘Software‘,‘09/23/2011 09:37:19 AM‘,‘Discount Software‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Sally Davisson‘, 871.12,‘Software‘,‘09/22/2011 05:21:28 PM‘,‘Discount Software‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Rod Kaplan‘, 2345.19,‘Computer Supplies‘,‘09/23/2011 5:01:11 PM‘,‘Discount Software‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Sandy Roberts‘, 76.38,‘Books‘,‘09/23/2011 4:51:57 PM‘,‘Computer Books and Software‘);

INSERT INTO dbo.SalesTransaction

VALUES (‘Marc Trotter‘, 562.94,‘Software‘,‘09/23/2011 6:51:43 PM‘,‘Computer Books and Software‘);

1:創建示例數據的腳本

如果看1中的腳本,就會發現我創建了dbo..Sales Transaction table。之後,我會將一些記錄插入到這個表中。我將使用這個表來演示如何使用一個簡單的GROUP BY子句來聚合數據。

按單個列分組

使用清單1創建的示例表,第一個示例將使用GROUP BY子句來基於單個列匯總數據。清單2中的示例總結了基於StoreName列的示例數據。

USE tempdb;

GO

SELECT StoreName

,SUM(TotalSalesAmount) AS StoreSalesAmount

FROM dbo.SalesTransaction

GROUP BY StoreName;

清單2:基於單個列的組

當清單2中的代碼在我的示例表中執行時,將返回報告1中的以下匯總行。

StoreName StoreSalesAmount

------------------------------------------ ----------------

Computer Books and Software 639.32

Discount Software 15757.28

The Software Outlet 1002.36

報告1:基於單個列匯總樣本數據。

如果看報告1中的輸出結果,可以看到,只有一個聚合行被返回,來獲得多個獨特的StoreName值。每個記錄的StoreSalesAmount都是通過使用SUM函數將每個商店的銷售記錄的TotalSalesAmount列相加來計算的。

分組由多個列

需要開發一份報告時,其中的數據需要把多個列進行分組。為了實現這一點,您需要做的就是在GROUP BY子句中添加額外的列。當在GROUP BY子句中添加多個列時,SQL Server將根據GROUP BY子句中各列的惟一組合值對它們行進行聚合。在清單3中,我通過在GROUP by子句中添加第二列,擴展了清單2中的查詢範圍。

USE tempdb;

GO

SELECT StoreName, SalesTypeDesc

,SUM(TotalSalesAmount) AS StoreSalesAmount

FROM dbo.SalesTransaction

GROUP BY StoreName, SalesTypeDesc;

清單3:基於單個列的組

當我根據示例數據運行清單3中的代碼時,我得到了報告2中的結果。

StoreName SalesTypeDesc StoreSalesAmount

---------------------------- ------------------ ----------------

Computer Books and Software Books 76.38

Discount Software Computer Supplies 14690.97

The Software Outlet Computer Supplies 119.01

Computer Books and Software Software 562.94

Discount Software Software 1066.31

The Software Outlet Software 883.35

報告2:運行清單1的輸出

在報告2中,您可以看到StoreSalesAmount現在是StoreName和SalesTypeDesc總級別。還要註意,返回的聚合一行不是按照GROUP BY子句中列的順序排序的。如果希望匯總數據以StoreName的順序出現,那麽就需要在SELECT語句中包含order BY子句。我將訂單添加到清單3中的代碼會返回StoreName訂單中的匯總數據。

Using an Expression in the GROUP BY Clause

有時,你可能希望將數據分組,而不是特定的列或列集。例如,你可能希望根據一些VARCHAR列的前幾個字符,或者僅僅是日期,或DATETIME列的月份來總結你的數據。SQL Server允許你在GROUP BY子句中指定表達式來完成此操作。表達式可以是基於正在聚合的詳細記錄集中的列的任何有效表達式。為了演示如何在GROUP BY子句中使用表達式,請查看清單4中的代碼。

USE tempdb;

GO

SELECT CONVERT(CHAR(10),SalesDateTime,101) AS SalesDate

,SUM(TotalSalesAmount) AS TotalSalesAmount

FROM dbo.SalesTransaction

GROUP BY CONVERT(CHAR(10),SalesDateTime,101);

Listing 4: GROUP BY based on Single columns

在清單4中,SELECT語句將基於表達式的數據分組,在本例中為轉換函數。如果在GROUP BY子句中使用表達式,則必須在SELECT列表中使用相同的表達式。CONVERT函數將解析SalesDateTime列,並只返回該列的日期部分。使用GROUP BY子句中的CONVERT函數,可以根據不同銷售記錄的實際日期對銷售數據進行匯總。通過這樣做,我可以總結我的示例,以獲得所有商店的總銷售額,如報告3所示。

SalesDate TotalSalesAmount

---------- ----------------

09/22/2011 1076.86

09/23/2011 16322.10

Report 3: Output when summarizing data based on expression

使用表達式可以讓你以編程方式識別您的詳細數據的哪些部分將被用於聚合數據。

HAVING Clause

如果你使用GROUP BY子句聚合數據,你可能希望不返回所有聚合的值。相反,你可能只想返回聚合值的一個子集。可以使用HAVING子句來選擇性地識別你想要從組中返回的聚合值。

通常,當我們選擇數據時,我們使用WHERE子句來限制返回的行。惟一的問題是WHERE子句操作行值,而不是聚合值。因此,WHERE子句不能使用GROUP by子句創建的聚合值。但是,在GROUP BY子句後面添加一個HAVING子句為您提供了一種指定條件來確定您想要返回的特定匯總值的方法。為了更好地理解這一點,我來舉幾個例子。

在查看商店銷售數據時,有一個常見的條款可能用於確定沒有達到特定銷售限額的商店。如果你想找到所有不滿足最低銷售金額的商店,你可以使用清單5中的代碼來實現。

USE tempdb;

GO

SELECT StoreName

,SUM(TotalSalesAmount) AS StoreSalesAmount

FROM dbo.SalesTransaction

GROUP BY StoreName

HAVING SUM(TotalSalesAmount) < 1000.00;

Listing 5: Restricting result set by using HAVING clause

在清單5中,我將結果集限制為那些累計總銷售額小於1000.00的商店。在我這個簡單的例子中,你會發現“計算機書籍和軟件”的StoreName是唯一一個沒有達到$1000.00的銷售配額數量的商店。

HAVING子句可以用於未聚合的列。如果你希望根據GROUP BY子句中使用的任何列的特定值來限制返回的行,那麽你也可以這樣做,清單6演示了這一點。

USE tempdb;

GO

SELECT StoreName

,SUM(TotalSalesAmount) AS StoreSalesAmount

FROM dbo.SalesTransaction

GROUP BY StoreName

HAVING StoreName LIKE ‘%Outlet%‘

OR StoreName LIKE ‘%Books%‘;

Listing 6: Restricting result set based on GROUP BY column

在清單6中,我只希望看到在他們的商店名稱中有“Outlet”或“Books”的商店的匯總數據,這個例子還表明在HAVING子句中可以有多個條件。另一種方法是考慮WHERE和HAVING之間的區別,即WHERE子句在數據被聚合之前過濾掉數據行,而HAVING子句在應用程序組之後過濾出聚集的行。

Summarizing Data with the Simple GROUP BY Clause

在本文中,我向你展示了如何使用簡單的GROUP BY子句來總結你的數據。我討論了如何使用單個列、多個列以及GROUP BY子句中的表達式來總結詳細數據。通過使用我所演示的內容,你現在應該能夠構建一個簡單的GROUP By子句來總結你的數據,並且可以選擇使用have來過濾匯總數據。

在我的下一篇文章中,我將擴展我對GROUP BY子句的討論。在這篇後續文章中,我將向你展示如何使用多維數據集和ROLLUP操作符來生成額外的匯總數據,如子總數和總值。

四巨頭第七周作業翻譯