目前為止的所有計(jì)算都是在表的所有數(shù)據(jù)或匹配特定的 WHERE 子句的
數(shù)據(jù)上進(jìn)行的。提示一下,下面的例子返回供應(yīng)商 1003 提供的產(chǎn)品數(shù)目
但如果要返回每個(gè)供應(yīng)商提供的產(chǎn)品數(shù)目怎么辦?或者返回只提供
單項(xiàng)產(chǎn)品的供應(yīng)商所提供的產(chǎn)品,或返回提供10個(gè)以上產(chǎn)品的供應(yīng)商怎
么辦?
這就是分組顯身手的時(shí)候了。分組允許把數(shù)據(jù)分為多個(gè)邏輯組,以
便能對(duì)每個(gè)組進(jìn)行聚集計(jì)算
分組是在 SELECT 語(yǔ)句的 GROUP BY 子句中建立的。理解分組的最好辦
法是看一個(gè)例子
因?yàn)槭褂昧?GROUP BY ,就不必指定要計(jì)算和估值的每個(gè)組了。系統(tǒng)
會(huì)自動(dòng)完成。 GROUP BY 子句指示MySQL分組數(shù)據(jù),然后對(duì)每個(gè)組而不是
整個(gè)結(jié)果集進(jìn)行聚集
在具體使用 GROUP BY 子句前,需要知道一些重要的規(guī)定。
使用 ROLLUP 使用 WITH ROLLUP 關(guān)鍵字,可以得到每個(gè)分組以
及每個(gè)分組匯總級(jí)別(針對(duì)每個(gè)分組)的值,如下所示
除了能用 GROUP BY 分組數(shù)據(jù)外,MySQL還允許過(guò)濾分組,規(guī)定包括
哪些分組,排除哪些分組。例如,可能想要列出至少有兩個(gè)訂單的所有
顧客。為得出這種數(shù)據(jù),必須基于完整的分組而不是個(gè)別的行進(jìn)行過(guò)濾
HAVING 非常類(lèi)似于 WHERE 。事實(shí)上,目前為止所
學(xué)過(guò)的所有類(lèi)型的 WHERE 子句都可以用 HAVING 來(lái)替代。唯一的差別是
WHERE 過(guò)濾行,而 HAVING 過(guò)濾分組
HAVING 支持所有 WHERE 操作符 在第6章和第7章中,我們學(xué)習(xí)
了 WHERE 子句的條件(包括通配符條件和帶多個(gè)操作符的子
句)。所學(xué)過(guò)的有關(guān) WHERE 的所有這些技術(shù)和選項(xiàng)都適用于
HAVING 。它們的句法是相同的,只是關(guān)鍵字有差別
這條 SELECT 語(yǔ)句的前3行類(lèi)似于上面的語(yǔ)句。最后一行增加了
HAVING 子句,它過(guò)濾 COUNT(*) >=2 (兩個(gè)以上的訂單)的那些
分組。
正如所見(jiàn),這里 WHERE 子句不起作用,因?yàn)檫^(guò)濾是基于分組聚集值而
不是特定行值的
HAVING 和 WHERE 的差別 這里有另一種理解方法, WHERE 在數(shù)據(jù)
分組前進(jìn)行過(guò)濾, HAVING 在數(shù)據(jù)分組后進(jìn)行過(guò)濾。這是一個(gè)重
要的區(qū)別, WHERE 排除的行不包括在分組中。這可能會(huì)改變計(jì)
算值,從而影響 HAVING 子句中基于這些值過(guò)濾掉的分組
那么,有沒(méi)有在一條語(yǔ)句中同時(shí)使用 WHERE 和 HAVING 子句的需要呢?
事實(shí)上,確實(shí)有。假如想進(jìn)一步過(guò)濾上面的語(yǔ)句,使它返回過(guò)去12個(gè)月
內(nèi)具有兩個(gè)以上訂單的顧客。為達(dá)到這一點(diǎn),可增加一條 WHERE 子句,過(guò)
濾出過(guò)去12個(gè)月內(nèi)下過(guò)的訂單。然后再增加 HAVING 子句過(guò)濾出具有兩個(gè)
以上訂單的分組
為更好地理解,請(qǐng)看下面的例子,它列出具有 2 個(gè)(含)以上、價(jià)格
為 10 (含)以上的產(chǎn)品的供應(yīng)商
雖然 GROUP BY 和 ORDER BY 經(jīng)常完成相同的工作,但它們是非常不同
的。表13-1匯總了它們之間的差別
表13-1中列出的第一項(xiàng)差別極為重要。我們經(jīng)常發(fā)現(xiàn)用 GROUP BY 分
組的數(shù)據(jù)確實(shí)是以分組順序輸出的。但情況并不總是這樣,它并不是SQL
規(guī)范所要求的。此外,用戶也可能會(huì)要求以不同于分組的順序排序。僅
因?yàn)槟阋阅撤N方式分組數(shù)據(jù)(獲得特定的分組聚集值),并不表示你需要
以相同的方式排序輸出。應(yīng)該提供明確的 ORDER BY 子句,即使其效果等
同于 GROUP BY 子句也是如此
不要忘記 ORDER BY 一般在使用 GROUP BY 子句時(shí),應(yīng)該也給
出 ORDER BY 子句。這是保證數(shù)據(jù)正確排序的唯一方法。千萬(wàn)
不要僅依賴 GROUP BY 排序數(shù)據(jù)
檢索總計(jì)訂單價(jià)格大于等于 50 的訂
單的訂單號(hào)和總計(jì)訂單價(jià)格
下面回顧一下 SELECT 語(yǔ)句中子句的順序。表13-2以在 SELECT 語(yǔ)句中
使用時(shí)必須遵循的次序,列出迄今為止所學(xué)過(guò)的子句
我們學(xué)習(xí)了如何用SQL聚集函數(shù)對(duì)數(shù)據(jù)進(jìn)行匯總計(jì)算。
本章講授了如何使用 GROUP BY 子句對(duì)數(shù)據(jù)組進(jìn)行這些匯總計(jì)算,返回每
個(gè)組的結(jié)果。我們看到了如何使用 HAVING 子句過(guò)濾特定的組,還知道了
ORDER BY 和 GROUP BY 之間以及 WHERE 和 HAVING 之間的差異。
聯(lián)系客服