使用SQL Server過濾資料的方法

iSQlServer發表於2009-12-14

  關係型資料通常以規範化形式儲存,就是說你應該儘可能少地重複資料;通常情況下,表與表之間僅通過各種鍵值實現關聯。進一步地講,規範化的含義就是:你不能在資料庫中儲存計算後的值,而你只能在需要的時候臨時計算資料庫中儲存的值。

  對資料進行某些分析通常是很重要的。比方說,你或許想知道哪些產品的定單最多或者哪些定單的利潤最大。這些問題都要求你針對自己的SQL語句建立執行過濾規則的公式。其中最重要的語句之一就是GROUP BY子句。

  Northwind資料庫中的定單

  Northwind資料庫是包含在SQL Server安裝軟體中的兩個示範資料庫。這個資料庫雖然談不上完美無缺但也足夠滿足我們討論GROUP BY語句的目的了。原因之一是它工作原理清晰,執行良好,包含了一整套標準的資料表,比如Customers(客戶)、Orders(定單)、Order Details(定單細節)和處理定單的Products(產品)。

  表的結構模式

  如果你想檢視各個定單的OrderID和ProductID ,以下的SQL命令可以滿足要求:

  SELECT o.OrderID, od.ProductID
  FROM Orders o, [Order Details] od
  WHERE o.OrderID = od.OrderID

  這樣你就通過OrderID欄位把Orders和Order Details連線了起來。給出的結果列表即顯示各定貨條目的OrderID和ProductID。

  你可以從這個列表中找到條目數量最大的定單。可是,再想想,要能簡單地要求資料庫計算出需要的條目數目不更方便嗎?如果你不關心單個條目而只想知道訂購條目數量最大的定單,那麼你可以採用以下的SQL語句:

  SELECT o.OrderID, Count(od.ProductID) as NumItems
  FROM Orders o, [Order Details] od
  WHERE o.OrderID = od.OrderID

  這樣就可以總計出產品的數量並用一個名為NumItems的新欄位來顯示總數。可是,如果你執行該語句則可能得到以下錯誤:

  Server: Msg 8118, Level 16, State 1, Line 1

  選擇語句中的'o.OrderID'列是無效的,因為它沒有包含在彙集函式之內而且沒有相應的GROUP BY 子句。

  在這種情況下,你實際上在總計ProductID,但OrderID卻沒有被計算總和或者有其他操作施加於其上。

  其實這個示例中計算的並不是訂購產品條目的總數而是特定訂購產品條目的數目。換句話說,你可以看到某一特定定單包括三種產品,但卻並不能表示客戶各訂購了5種。你得到的正是按照定單統計的產品總量。你應該用GROUP BY字句來檢視訂購產品的總數。

  使用GROUP BY

  使用GROUP BY就好比提出下面的問題:“我如何檢視資料?“如果答案是“按照”某種要素來看那麼你就可能用到GROUP BY。就我們的例子來說,你希望按照定單檢視產品的數量,所以你就可以用OrderID欄位進行分組。此外,採用ORDER BY 子句可以更容易地找出訂購條目最多的定單。新的查詢語句如下所示:

  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

  現在你就得到問題的答案了。如圖B所示的部分結果,定單號11077訂購了25種產品,而排第2的最大定單則只訂購了6類產品。

  理解規則

  GROUP BY具有相當高的靈活性,當然你還得遵守相應的語法規則。比如說,你可以在ORDER BY 子句中包含多個表列。如果你想檢視每一客戶訂購產品各個型別的數量,那麼你必須通過定單建立查詢把客戶連線到產品。圖A顯示的4表連線顯然就要用到了。之後你要根據客戶和產品進行分組同時對Order Details表內的Quantity列計算總和。查詢語句如下:

  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

  查詢結果顯示出資料庫內每一客戶購買各類產品的總數。

  同時,你還可以在查詢中置入多個彙集列。例如,假設你想檢視的定單列表要顯示單一專案的最大購買量以及該定單的專案總數,那麼以下的語句就可以用Max函式來顯示單一專案的最大訂購量。這種方法還能對所購專案總量求和。

  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

  現在你得到了定單、訂購量排前列的數量以及定單總項。

  GROUP BY是過濾資料的一種強有力的工具。為了在你的SQL表內計算資料,它的功能不可小看。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-622381/,如需轉載,請註明出處,否則將追究法律責任。

相關文章