Group by與having理解數據庫
注意:select 後的字段,必需要麼包含在group by中,要麼包含在having 後的聚合函數裏。函數
1. GROUP BY 是分組查詢, 通常 GROUP BY 是和聚合函數配合使用學習
group by 有一個原則,就是 select 後面的全部列中,沒有使用聚合函數的列,必須出如今 group by 後面(重要)spa
例如,有以下數據庫表:code
A B
1 abc
1 bcdblog
1 asdfgtable
若是有以下查詢語句(該語句是錯誤的,緣由見前面的原則)class
select A,B from table group by A
該查詢語句的意圖是想獲得以下結果(固然只是一相情願)基礎
A B
abc
1 bcdselect
asdfg
右邊3條如何變成一條,因此須要用到聚合函數,以下(下面是正確的寫法):
select A,count(B) ,max(B)as 數量 from table group by A
這樣的結果就是
A 數量
1 3
2. Having
where 子句的做用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分組以前過濾數據,條件中不能包含聚組函數,使用where條件顯示特定的行。
having 子句的做用是篩選知足條件的組,即在分組以後過濾數據,條件中常常包含聚組函數,使用having 條件顯示特定的組,也可使用多個分組標準進行分組。
having 子句被限制子已經在SELECT語句中定義的列和聚合表達式上。一般,你須要經過在HAVING子句中重複聚合函數表達式來引用聚合值,就如你在SELECT語句中作的那樣。例如:
SELECT A COUNT(B) FROM TABLE GROUP BY A HAVING COUNT(B)>2
3.使用compute和compute by
使用compute子句容許同時觀察查詢所獲得各列的數據的細節以及統計各列數據所產生的彙總列
select * from work [查詢所獲得的各列的數據的細節]
compute max(基本工資),min(基本工資) [統計以後的結果]
這個例子中沒有使用by關鍵字,返回的結果是最後添加了一行基本工資的最大值和最小值,也可增長by關鍵字.
例:select * from work order by 學歷
compute max(基本工資),min(基本工資) by 學歷
比較:select 學歷,max(基本工資),min(基本工資) from work group by 學歷
說明:1:compute子句必須與order by子句用在一塊兒
2:compute子句能夠返回多種結果集.一種是體現數據細節的數據集,能夠按分類要求進行正確的分類;另外一種在分類的基礎上進行彙總產生結果.
3:而group by子句對每一類數據分類以後只能產生一個結果,不能知道細節
示例學習Northwind數據庫:
非相關查詢:
1:返回每一個美國員工都爲其處理過訂單的全部客戶
--思路:1:Employees表中獲取美國員工總數2:Orders表中查詢美國員工處理的Order,對CustomerID分組後,統計其不一樣的EmployeeID正好等於美國員工總數
Select CustomerID From Orders Where EmployeeID In --獲得美國員工服務 的客戶
(Select EmployeeID From Employees Where Country=N'USA') -- 獲得所有美國員工id
group by CustomerID --按客戶分組
Having Count(Distinct EmployeeID)= --爲其處理訂單的distinct 員工數等於美國總員工數
(Select Count(*) From Employees Where Country=N'USA')--美國員工總數
2:
返回在每個月最後實際訂單日期發生的訂單(每個月最後訂單日期可能不是每個月最後一天)
--思路:子查詢按月分組獲得每個月最近訂單日期
Select OrderID,CustomerID,EmployeeID,OrderDate
From Orders
Where OrderDate In
(Select Max(OrderDate) From Orders Group by Convert(char(6),OrderDate,112))--112表示YYYYMMDD char(6)提取YYYYMM
3.
Select字句在邏輯上是SQL語句最後進行處理的最後一步,因此,如下查詢會發生錯誤:
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
FROM (SELECT YEAR(OrderDate) AS OrderYear, CustomerID
FROM dbo.Orders) AS D
GROUP BY OrderYear
;由於group by是在Select以前進行的,那個時候orderYear這個列並無造成。
若是要查詢成功,能夠像下面進行修改:
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
FROM (SELECT YEAR(OrderDate) AS OrderYear, CustomerID
FROM dbo.Orders) AS D
GROUP BY OrderYear;還有一種很特殊的寫法:
SELECT OrderYear, COUNT(DISTINCT CustomerID) AS NumCusts
FROM (SELECT YEAR(OrderDate), CustomerID
FROM dbo.Orders) AS D(OrderYear, CustomerID)
GROUP BY OrderYear;在做者眼裏,他是很是喜歡這種寫法的,由於更清晰,更明確,更便於維護。
在查詢中使用參數定向產生一批結果,這個技巧沒有什麼好說的。
嵌套查詢,在處理邏輯上是從裏向外進行執行的。