時(shí)間:2015-06-28 00:00:00 來(lái)源:IT貓撲網(wǎng) 作者:網(wǎng)管聯(lián)盟 我要評(píng)論(0)
我們知道,關(guān)系型數(shù)據(jù)一般以規(guī)范化的形式保存,也就是說(shuō)你應(yīng)該盡可能少地重復(fù)數(shù)據(jù);在正常情況下,表與表之間僅通過(guò)各種鍵值實(shí)現(xiàn)關(guān)聯(lián)。進(jìn)一步地講,規(guī)范化的含義就是:你不能在數(shù)據(jù)庫(kù)中保存計(jì)算后的值,而你只能在需要的時(shí)候臨時(shí)計(jì)算數(shù)據(jù)庫(kù)中保存的值。
對(duì)數(shù)據(jù)進(jìn)行某些分析通常是很重要的。比方說(shuō),你或許想知道哪些產(chǎn)品的定單最多或者哪些定單的利潤(rùn)最大。這些問(wèn)題都要求你針對(duì)自己的SQL語(yǔ)句創(chuàng)建執(zhí)行過(guò)濾規(guī)則的公式。其中最重要的語(yǔ)句之一就是GROUP BY子句。
◆Northwind數(shù)據(jù)庫(kù)中的定單
Northwind數(shù)據(jù)庫(kù)是包含在SQL Server安裝軟件中的兩個(gè)示范數(shù)據(jù)庫(kù)。這個(gè)數(shù)據(jù)庫(kù)雖然談不上完美無(wú)缺但也足夠滿足我們討論GROUP BY語(yǔ)句的目的了。原因之一是它工作原理清晰,運(yùn)行良好,包含了一整套標(biāo)準(zhǔn)的數(shù)據(jù)表,比如Customers(客戶)、Orders(定單)、Order Details(定單細(xì)節(jié))和處理定單的Products(產(chǎn)品)。
◆表的結(jié)構(gòu)模式
如果你想查看各個(gè)定單的OrderID和ProductID ,以下的SQL命令可以滿足要求:
以下為引用的內(nèi)容:
SELECT o.OrderID, od.ProductID
FROM Orders o, [Order Details] od
WHERE o.OrderID = od.OrderID
這樣你就通過(guò)OrderID字段把Orders和Order Details連接了起來(lái)。給出的結(jié)果列表即顯示各定貨條目的OrderID和ProductID。
你可以從這個(gè)列表中找到條目數(shù)量最大的定單??墒?,再想想,要能簡(jiǎn)單地要求數(shù)據(jù)庫(kù)計(jì)算出需要的條目數(shù)目不更方便嗎?如果你不關(guān)心單個(gè)條目而只想知道訂購(gòu)條目數(shù)量最大的定單,那么你可以采用以下的SQL語(yǔ)句:
以下為引用的內(nèi)容:
SELECT o.OrderID, Count(od.ProductID) as NumItems
FROM Orders o, [Order Details] od
WHERE o.OrderID = od.OrderID
?
這樣就可以總計(jì)出產(chǎn)品的數(shù)量并用一個(gè)名為NumItems的新字段來(lái)顯示總數(shù)??墒?,如果你執(zhí)行該語(yǔ)句則可能得到以下錯(cuò)誤:
以下為引用的內(nèi)容:
Server: Msg 8118, Level 16, State 1, Line 1
選擇語(yǔ)句中的'o.OrderID'列是無(wú)效的,因?yàn)樗鼪](méi)有包含在匯集函數(shù)之內(nèi)而且沒(méi)有相應(yīng)的GROUP BY 子句。
在這種情況下,你實(shí)際上在總計(jì)ProductID,但OrderID卻沒(méi)有被計(jì)算總和或者有其他操作施加于其上。
其實(shí)這個(gè)示例中計(jì)算的并不是訂購(gòu)產(chǎn)品條目的總數(shù)而是特定訂購(gòu)產(chǎn)品條目的數(shù)目。換句話說(shuō),你可以看到某一特定定單包括三種產(chǎn)品,但卻并不能表示客戶各訂購(gòu)了5種。你得到的正是按照定單統(tǒng)計(jì)的產(chǎn)品總量。你應(yīng)該用GROUP BY字句來(lái)查看訂購(gòu)產(chǎn)品的總數(shù)。
◆使用GROUP BY
使用GROUP BY就好比提出下面的問(wèn)題:"我如何查看數(shù)據(jù)?"如果答案是"按照"某種要素來(lái)看那么你就可能用到GROUP BY。就我們的例子來(lái)說(shuō),你希望按照定單查看產(chǎn)品的數(shù)量,所以你就可以用OrderID字段進(jìn)行分組。此外,采用ORDER BY 子句可以更容易地找出訂購(gòu)條目最多的定單。新的查詢語(yǔ)句如下所示:
以下為引用的內(nèi)容:
SELECT o.OrderID, Count(od.ProductID) as NumItems
FROM Orders o, [Order Details] od
WHERE o.OrderID = od.OrderID
GROUP BY o.OrderID
ORDER BY NumItems DESC
現(xiàn)在你就得到問(wèn)題的答案了。
◆理解規(guī)則
GROUP BY具有相當(dāng)高的靈活性,當(dāng)然你還得遵守相應(yīng)的語(yǔ)法規(guī)則。比如說(shuō),你可以在ORDER BY 子句中包含多個(gè)表列。如果你想查看每一客戶訂購(gòu)產(chǎn)品各個(gè)類型的數(shù)量,那么你必須通過(guò)定單創(chuàng)建查詢把客戶連接到產(chǎn)品。圖A顯示的4表連接顯然就要用到了。之后你要根據(jù)客戶和產(chǎn)品進(jìn)行分組同時(shí)對(duì)Order Details表內(nèi)的Quantity列計(jì)算總和。查詢語(yǔ)句如下:
以下為引用的內(nèi)容:
SELECT c.CompanyName, p.ProductName, Sum(od.Quantity) as TotalBought
FROM Customers c, Products p, Orders o, [Order Details] od
WHERE
c.CustomerID=o.CustomerID AND
o.OrderID=od.OrderID AND
od.ProductID=p.ProductID
GROUP BY c.CompanyName, p.ProductName
ORDER BY CompanyName, TotalBought DESC
查詢結(jié)果顯示出數(shù)據(jù)庫(kù)內(nèi)每一客戶購(gòu)買各類產(chǎn)品的總數(shù)。
同時(shí),你還可以在查詢中置入多個(gè)匯集列。例如,假設(shè)你想查看的定單列表要顯示單一項(xiàng)目的最大購(gòu)買量以及該定單的項(xiàng)目總數(shù),那么以下的語(yǔ)句就可以用Max函數(shù)來(lái)顯示單一項(xiàng)目的最大訂購(gòu)量。這種方法還能對(duì)所購(gòu)項(xiàng)目總量求和。
以下為引用的內(nèi)容:
SELECT o.OrderID,
Max(od.Quantity) as TopItem,
Sum(od.Quantity) as TotalBought
FROM
Orders o,
[Order Details] od,
Products p
WHERE
o.OrderID = od.OrderID AND
od.ProductID=p.ProductID
GROUP BY o.OrderID
ORDER BY TotalBought DESC
關(guān)鍵詞標(biāo)簽:SQL Server
相關(guān)閱讀
熱門文章 淺談JSP JDBC來(lái)連接SQL Server 2005的方法 SqlServer2005對(duì)現(xiàn)有數(shù)據(jù)進(jìn)行分區(qū)具體步驟 sql server系統(tǒng)表?yè)p壞的解決方法 MS-SQL2005服務(wù)器登錄名、角色、數(shù)據(jù)庫(kù)用戶、角色、架構(gòu)的關(guān)系
人氣排行 配置和注冊(cè)O(shè)DBC數(shù)據(jù)源-odbc數(shù)據(jù)源配置教程 如何遠(yuǎn)程備份(還原)SQL2000數(shù)據(jù)庫(kù) SQL2000數(shù)據(jù)庫(kù)遠(yuǎn)程導(dǎo)入(導(dǎo)出)數(shù)據(jù) SQL2000和SQL2005數(shù)據(jù)庫(kù)服務(wù)端口查看或修改 修改Sql Server唯一約束教程 SQL Server 2005降級(jí)到2000的正確操作步驟 sql server系統(tǒng)表?yè)p壞的解決方法 淺談JSP JDBC來(lái)連接SQL Server 2005的方法