如果你編寫 SQL 查詢已有一段時(shí)間,那么你可能對(duì) WHERE 子句非常熟悉。雖然它對(duì)聚合字段沒(méi)有影響,但有一種方法可以根據(jù)聚合值過(guò)濾記錄,那就是使用 HAVING 子句。本博客將介紹它的工作原理,并提供幾個(gè)在 SELECT 查詢中使用它的示例。


聚合和 Having 子句


聚合通常與分組結(jié)合使用。在 SQL 中,可以使用 GROUP BY 子句來(lái)實(shí)現(xiàn)。通過(guò)聚合和分組,我們可以深入了解數(shù)據(jù)。例如,一家電子商務(wù)公司可能希望跟蹤特定時(shí)間段內(nèi)的銷售情況。


在很多情況下,我們可能不想在整個(gè)數(shù)據(jù)集上應(yīng)用 GROUP BY 子句。在這種情況下,我們可以使用 GROUP BY 命令和有條件的 HAVING 子句來(lái)篩掉不需要的結(jié)果。與 WHERE 子句類似,HAVING 指定了一個(gè)或多個(gè)篩選條件,但針對(duì)的是一個(gè)組或一個(gè)聚合。因此,HAVING 總是放在 WHERE GROUP BY 子句之后,而在(可選的)ORDER BY 子句之前:



一些實(shí)例


為了更好地了解 HAVING 如何工作,讓我們通過(guò) Sakila 示例數(shù)據(jù)庫(kù) 運(yùn)行幾個(gè) SELECT 查詢。


我們的第一個(gè)查詢列出了租片次數(shù)最多的人,按降序排序,這樣租片次數(shù)最多的人就排在最前面。我們將使用 HAVING 子句刪除租片次數(shù)少于 3 次的客戶,以在一定程度上縮短列表:



下面是 Navicat Premium 中的查詢及其結(jié)果的第一頁(yè):



從這些租金數(shù)字來(lái)看,我們還可以再進(jìn)一步縮小列表長(zhǎng)度!


通過(guò) WHERE HAVING 篩選行


正如 GROUP BY ORDER BY 應(yīng)用于查詢過(guò)程的不同階段一樣,WHERE HAVING 也是如此。因此,我們可以在分組和聚合之前和之后加入這兩個(gè)子句來(lái)篩選結(jié)果。例如,我們可以添加一個(gè) WHERE 子句,將結(jié)果限制在給定年份的上半年:



下面是在 Navicat Premium 中運(yùn)行的上述查詢及其結(jié)果的第一頁(yè):



組合多個(gè)條件


正如 WHERE 子句使用 AND OR 關(guān)鍵字支持多個(gè)條件一樣,HAVING 子句也是如此。例如,我們可以將 HAVING 子句修改為類似下面的內(nèi)容,從而找到租金數(shù)字在給定范圍內(nèi)的客戶:


HAVING total_rentals >= 3 AND total_rentals <= 10