《SQL必知必會(huì)》第 10 課 分組數(shù)據(jù)

目標(biāo):

10.1 數(shù)據(jù)分組

10.2 創(chuàng)建分組

10.3 過濾分組

10.4 分組和排序

10.5 SELECT 子句順序

這一課介紹如何分組數(shù)據(jù)炸宵,以便匯總表內(nèi)容的子集筐乳。這涉及兩個(gè)新

SELECT 語句子句:GROUP BY 子句和 HAVING 子句衅澈。


10.1 數(shù)據(jù)分組

使用分組可以將數(shù)據(jù)分為多個(gè)邏輯組,對(duì)每個(gè)組進(jìn)行聚集計(jì)算展蒂。

10.2 創(chuàng)建分組

SELECT vend_id, COUNT(*) AS num_prods

FROM Products

GROUP BY vend_id;#分組根據(jù)

輸出:# vend_id num_prods?FNG01 2? DLL01 4? BRS01 3


在使用 GROUP BY 子句前呢簸,需要知道一些重要的規(guī)定。?

1. GROUP BY 子句可以包含任意數(shù)目的列漓概,因而可以對(duì)分組進(jìn)行嵌套漾月,更細(xì)致地進(jìn)行數(shù)據(jù)分組。?

2.如果在 GROUP BY 子句中嵌套了分組胃珍,數(shù)據(jù)將在最后指定的分組上進(jìn)行匯總栅屏。換句話說,在建立分組時(shí)堂鲜,指定的所有列都一起計(jì)算(所以不能從個(gè)別的列取回?cái)?shù)據(jù))栈雳。?

3. GROUP BY 子句中列出的每一列都必須是檢索列或有效的表達(dá)式(但不能是聚集函數(shù))。如果在 SELECT 中使用表達(dá)式缔莲,則必須在 GROUP BY 子句中指定相同的表達(dá)式哥纫。不能使用別名。

4.大多數(shù)SQL 實(shí)現(xiàn)不允許 GROUP BY 列帶有長度可變的數(shù)據(jù)類型(如文本或備注型字段)痴奏。

5.除聚集計(jì)算語句外蛀骇,SELECT 語句中的每一列都必須在 GROUP BY 子句中給出。?

6.如果分組列中包含具有 NULL 值的行读拆,則 NULL 將作為一個(gè)分組返回擅憔。 如果列中有多行 NULL 值,它們將分為一組檐晕。?

7.GROUP BY 子句必須出現(xiàn)在 WHERE 子句之后暑诸,ORDER BY 子句之前蚌讼。

提示:ALL 子句?

Microsoft SQL Server 等有些 SQL 實(shí)現(xiàn)在 GROUP BY 中支持可選的 ALL 子句。這個(gè)子句可用來返回所有分組个榕,即使是沒有匹配行的分組也返 回(在此情況下篡石,聚集將返回 NULL)。具體的 DBMS 是否支持 ALL西采, 請(qǐng)參閱相應(yīng)的文檔凰萨。

注意:通過相對(duì)位置指定列

有的 SQL 實(shí)現(xiàn)允許。例如械馆,GROUP BY 2, 1 可表示按選擇的第二個(gè)列分組胖眷,然后再按第一個(gè)列分組。雖然這種速記語法很方便霹崎,但并非所有 SQL 實(shí)現(xiàn)都支持珊搀,并且使用它容易在編輯 SQL 語句時(shí)出錯(cuò)。

10.3 過濾分組( HAVING? 關(guān)鍵詞)

提示:HAVING 支持所有 WHERE 操作符

在第 4 課和第 5 課中仿畸,我們學(xué)習(xí)了 WHERE 子句的條件(包括通配符條件和帶多個(gè)操作符的子句)。學(xué)過的這些有關(guān) WHERE 的所有技術(shù)和選項(xiàng)都適用于 HAVING朗和。它們的句法是相同的错沽,只是關(guān)鍵字有差別。

說明:HAVING 和 WHERE 的差別 這里有另一種理解方法眶拉,WHERE 在數(shù)據(jù)分組前進(jìn)行過濾千埃,HAVING 在數(shù)據(jù)分組后進(jìn)行過濾。這是一個(gè)重要的區(qū)別忆植,WHERE 排除的行不包括在 分組中放可。這可能會(huì)改變計(jì)算值,從而影響 HAVING 子句中基于這些值過濾掉的分組朝刊。

SELECT cust_id, COUNT(*) AS orders

FROM Orders

GROUP BY cust_id

HAVING COUNT(*) >= 2;

輸出:# cust_id, orders?'1000000001', '2'


SELECT vend_id, COUNT(*) AS num_prods?

FROM Products?

WHERE prod_price >= 4?

GROUP BY vend_id?

HAVING COUNT(*) >= 2;

輸出:'FNG01', '2' 'BRS01', '3'


說明:使用 HAVING 和 WHERE?

HAVING 與 WHERE 非常類似耀里,如果不指定 GROUP BY,則大多數(shù) DBMS 會(huì)同等對(duì)待它們拾氓。不過冯挎,你自己要能區(qū)分這一點(diǎn)。使用 HAVING 時(shí)應(yīng) 該結(jié)合 GROUP BY 子句咙鞍,而 WHERE 子句用于標(biāo)準(zhǔn)的行級(jí)過濾房官。

10.4 分組和排序

提示:不要忘記 ORDER BY

一般在使用 GROUP BY 子句時(shí),應(yīng)該也給出 ORDER BY 子句续滋。這是保證數(shù)據(jù)正確排序的唯一方法翰守。千萬不要僅依賴 GROUP BY 排序數(shù)據(jù)。

SELECT order_num, COUNT(*) AS items

FROM OrderItems

GROUP BY order_num

HAVING COUNT(*) >= 3;

輸出:


SELECT order_num, COUNT(*) AS items?

FROM OrderItems?

GROUP BY order_num?

HAVING COUNT(*) >= 3?

ORDER BY items,order_num;

輸出:

10.5 SELECT 子句順序

10.6 小結(jié)

上一課介紹了如何用 SQL 聚集函數(shù)對(duì)數(shù)據(jù)進(jìn)行匯總計(jì)算疲酌。這一課講授了如何使用 GROUP BY 子句對(duì)多組數(shù)據(jù)進(jìn)行匯總計(jì)算蜡峰,返回每個(gè)組的結(jié)果。我們看到了如何使用 HAVING 子句過濾特定的組,還知道了 ORDER BY和 GROUP BY 之間以及 WHERE 和 HAVING 之間的差異事示。

-- ----------第10課 分組數(shù)據(jù)----------------------

-- 10.1 數(shù)據(jù)分組

-- 10.2 創(chuàng)建分組

SELECT vend_id, COUNT(*) AS num_prods

FROM Products

GROUP BY vend_id;

-- 10.3 過濾分組

SELECT cust_id, COUNT(*) AS orders

FROM Orders

GROUP BY cust_id

HAVING COUNT(*) >= 2;

SELECT vend_id, COUNT(*) AS num_prods

FROM Products

WHERE prod_price >= 4

GROUP BY vend_id

HAVING COUNT(*) >= 2;

-- 10.4 分組和排序

SELECT order_num, COUNT(*) AS items

FROM OrderItems

GROUP BY order_num

HAVING COUNT(*) >= 3;

SELECT order_num, COUNT(*) AS items

FROM OrderItems

GROUP BY order_num

HAVING COUNT(*) >= 3

ORDER BY items,order_num;

-- 10.5 SELECT 子句順序

10.7 挑戰(zhàn)題

1. OrderItems 表包含每個(gè)訂單的每個(gè)產(chǎn)品早像。編寫 SQL 語句,返回每個(gè)訂單號(hào)(order_num)各有多少行數(shù)(order_lines)肖爵,并按 order_lines對(duì)結(jié)果進(jìn)行排序卢鹦。

SELECT order_num,count(*) AS order_lines

FROM orderitems

GROUP BY order_num

ORDER BY order_lines;

2. 編寫 SQL 語句,返回名為 cheapest_item 的字段劝堪,該字段包含每個(gè)供應(yīng)商成本最低的產(chǎn)品(使用 Products 表中的 prod_price)冀自,然后從最低成本到最高成本對(duì)結(jié)果進(jìn)行排序。

SELECT vend_id,MIN(prod_price) AS cheapest_item

FROM products

GROUP BY vend_id

ORDER BY cheapest_item;

3. 確定最佳顧客非常重要秒啦,請(qǐng)編寫 SQL 語句熬粗,返回至少含 100 項(xiàng)的所有訂單的訂單號(hào)(OrderItems 表中的 order_num)。

SELECT order_num

FROM OrderItems

GROUP BY order_num

HAVING SUM(quantity) >= 100

ORDER BY order_num;

4. 確定最佳顧客的另一種方式是看他們花了多少錢余境。編寫 SQL 語句驻呐,返回總價(jià)至少為 1000 的所有訂單的訂單號(hào)(OrderItems 表中的order_num)。提示:需要計(jì)算總和(item_price 乘以quantity)芳来。按訂單號(hào)對(duì)結(jié)果進(jìn)行排序含末。

SELECT order_num, SUM(item_price*quantity) AS total_price

FROM OrderItems

GROUP BY order_num

HAVING SUM(item_price*quantity) >= 1000

ORDER BY order_num;

5. 下面的 SQL 語句有問題嗎?(嘗試在不運(yùn)行的情況下指出即舌。)SELECT order_num, COUNT(*) AS items

FROM OrderItems

GROUP BY items

HAVING COUNT(*) >= 3

ORDER BY items, order_num;

SELECT order_num, COUNT(*) AS items

FROM OrderItems

GROUP BY order_num

HAVING COUNT(*) >= 3

ORDER BY items, order_num;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末佣盒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子顽聂,更是在濱河造成了極大的恐慌肥惭,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件紊搪,死亡現(xiàn)場離奇詭異蜜葱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)耀石,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門笼沥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人娶牌,你說我怎么就攤上這事奔浅。” “怎么了诗良?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵汹桦,是天一觀的道長。 經(jīng)常有香客問我鉴裹,道長舞骆,這世上最難降的妖魔是什么钥弯? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮督禽,結(jié)果婚禮上脆霎,老公的妹妹穿的比我還像新娘。我一直安慰自己狈惫,他們只是感情好睛蛛,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胧谈,像睡著了一般忆肾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上菱肖,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天客冈,我揣著相機(jī)與錄音,去河邊找鬼稳强。 笑死场仲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的退疫。 我是一名探鬼主播渠缕,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蹄咖!你這毒婦竟也來了褐健?” 一聲冷哼從身側(cè)響起付鹿,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤澜汤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后舵匾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俊抵,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年坐梯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了徽诲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吵血,死狀恐怖谎替,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蹋辅,我是刑警寧澤钱贯,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站侦另,受9級(jí)特大地震影響秩命,放射性物質(zhì)發(fā)生泄漏尉共。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一弃锐、第九天 我趴在偏房一處隱蔽的房頂上張望袄友。 院中可真熱鬧,春花似錦霹菊、人聲如沸剧蚣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽券敌。三九已至,卻和暖如春柳洋,著一層夾襖步出監(jiān)牢的瞬間待诅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來泰國打工熊镣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卑雁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓绪囱,卻偏偏與公主長得像测蹲,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鬼吵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容