group by 有一個原則,就是 select 后面的所有列中,沒有使用聚合函數的列,必須出現在 group by 后面(重要)
例如,有如下數據庫表:
A B
1 abc
1 bcd
1 asdfg
如果有如下查詢語句(該語句是錯誤的,原因見前面的原則)
select A,B from table group by A
該查詢語句的意圖是想得到如下結果(當然只是一相情願)
A B
abc
1 bcd
asdfg
右邊3條如何變成一條,所以需要用到聚合函數,如下(下面是正確的寫法):
select A,count(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;還有一種很特殊的寫法: