SQL學習之HAVING過濾分組


1、SQL除了能用Group By分組數據之外,SQL還允許過濾分組,規定包括那些分組,排除那些分組。例如,你可能想要列出至少有兩個訂單的所有顧客。為此,必須基於完整的分組而不是個別的行進行過濾。

    基於上面的例子,我們第一時間想到的是通過使用WHERE來過濾數據,拿到我們想要的結果,但是在這個列子中WHERE不能完成任務,因為WHERE過濾指定的是行,而不是分組。事實上,WHERE沒有分組的概念。

    因此,SQL提供了專門用來過濾分組的類似與WHERE子句的子句,HAVING子句,事實上,幾乎所有類型的WHERE子句都可以用HAVING來代替。唯一的差別是,WHERE過濾行數據,HAVING過濾分組數據。

如下代碼:

select * from dbo.T_Unit_Equipment

現在有一個報表系統,需要展示每個單位,擁有每台設備的數量,這個時候用WHERE很麻煩(前提是數據量比較少的情況下),下面是解決代碼:

select UnitId,EquipmentName,COUNT(*) as Equipments from dbo.T_Unit_Equipment group by UnitId,EquipmentName order by UnitId ASC

ok,完成需求!

現在,改變需求,現在需要檢索出每家單位擁有的同一種設備大於等於2的記錄,下面是解決代碼:

select UnitId,EquipmentName,COUNT(*) as Equipments from dbo.T_Unit_Equipment group by UnitId,EquipmentName HAVING COUNT(*)>=2 order by UnitId ASC 

ok,完成需求!

上面的代碼通過UnitId,EquipmentName兩個字段進行分組,然后SELECT語句檢索出UnitId,EquipmentName,以及Equipments(Equipments在這里是一個計算字段,通過COUNT()函數計算出每個分組的總記錄數),然后HAVING子句告訴SELECT語句只檢索出所有分組中的總記錄數大於等於2的分組記錄。這里的COUNT(*)>=2過濾了每家單位所擁有的同一種設備小於2的分組!

 

2、WHERE和HAVING的差別:

(1)WHERE在數據分組前進行過濾,HAVING在數據分組之后進行過濾,這是個很重要的區別,WHERE排除的行不包括在分組中。這可能會改變計算值,從而影響HAVING子句中基於這些值的過濾掉的分組,根據這個差別,我們可以確定WHERE子句和Group By子句的位置:WHERE子句會在數據分組之前,對行數據進行過濾。

(2)HAVING與WHERE非常類似,如果不指定Group By,則大多數DBMS會同等的對待他們,不過你自己要區分這一點,使用HAVING時應該結合Group By子句,而WHERE子句用於標准的行級數據過濾

下面通過一個例子來了解HAVING子句與WHERE子句的差別

select * from dbo.T_Unit_Equipment

現在需要檢索出每家單位擁有的同一種設備大於等於2的記錄,前提是設備必須有維護人員(對應表中的Person列值不能為空),下面是解決代碼:

select UnitId,EquipmentName,COUNT(*) as Equipments from dbo.T_Unit_Equipment where Person!='' group by UnitId,EquipmentName HAVING COUNT(*)>=1 order by UnitId ASC 

ok,完成需求!

where 過濾了Person=''的列值,然后Group By在對剩余的數據進行分組,之后HAVING子句進行分組過濾!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM