SQL語(yǔ)句--Group By總結(jié)
1SQL語(yǔ)句--GroupBy總結(jié)
1.GroupBy語(yǔ)句簡(jiǎn)介:
GroupBy語(yǔ)句從英文的字面意義上理解就是“根據(jù)(by)一定的規(guī)則進(jìn)行分組(Group)”。它的作用是通過(guò)一定的規(guī)則將一個(gè)數(shù)據(jù)集劃分成若干個(gè)小的區(qū)域,然后針對(duì)若干個(gè)小區(qū)域進(jìn)行數(shù)據(jù)處理。
P.S.這里真是體會(huì)到了一個(gè)好的命名的力量,GroupBy從字面是直接去理解是非常好理解的。恩,以后在命名的環(huán)節(jié)一定要加把勁:)。話(huà)題扯遠(yuǎn)了。
2.GroupBy的使用:
上面已經(jīng)給出了對(duì)GroupBy語(yǔ)句的理解;谶@個(gè)理解和SQLServer201*的聯(lián)機(jī)幫助,下面對(duì)GroupBy語(yǔ)句的各種典型使用進(jìn)行依次列舉說(shuō)明。
2.1GroupBy[Expressions]:
這個(gè)恐怕是GroupBy語(yǔ)句最常見(jiàn)的用法了,GroupBy+[分組字段](可以有多個(gè))。在執(zhí)行了這個(gè)操作以后,數(shù)據(jù)集將根據(jù)分組字段的值將一個(gè)數(shù)據(jù)集劃分成各個(gè)不同的小組。比如有如下數(shù)據(jù)集,其中水果名稱(chēng)(FruitName)和出產(chǎn)國(guó)家(ProductPlace)為聯(lián)合主鍵:
FruitNameProductPlacePriceAppleChina$1.1AppleJapan$2.1AppleUSA$2.5
OrangeChina$0.8
BananaChina$3.1PeachUSA$3.0
如果我們想知道每個(gè)國(guó)家有多少種水果,那么我們可以通過(guò)如下SQL語(yǔ)句來(lái)完成:
SELECTCOUNT(*)AS水果種類(lèi),ProductPlaceAS出產(chǎn)國(guó)FROMT_TEST_FRUITINFOGROUPBYProductPlace
這個(gè)SQL語(yǔ)句就是使用了GroupBy+分組字段的方式,那么這句SQL語(yǔ)句就可以解釋成“我按照出產(chǎn)國(guó)家(ProductPlace)將數(shù)據(jù)集進(jìn)行分組,然后分別按照各個(gè)組來(lái)統(tǒng)計(jì)各自的記錄數(shù)量。”很好理解對(duì)吧。這里值得注意的是結(jié)果集中有兩個(gè)返回字段,一個(gè)是ProductPlace(出產(chǎn)國(guó)),一個(gè)是水果種類(lèi)。如果我們這里水果種類(lèi)不是用Count(*),而是類(lèi)似如下寫(xiě)法的話(huà):
SELECTFruitName,ProductPlaceFROMT_TEST_FRUITINFOGROUPBYProductPlace
那么SQL在執(zhí)行此語(yǔ)句的時(shí)候會(huì)報(bào)如下的類(lèi)似錯(cuò)誤:
選擇列表中的列"T_TEST_FRUITINFO.FruitName"無(wú)效,因?yàn)樵摿袥](méi)有包含在聚合函數(shù)或GROUPBY子句中。
這就是我們需要注意的一點(diǎn),如果在返回集字段中,這些字段要么就要包含在GroupBy語(yǔ)句的后面,作為分組的依據(jù);要么就要被包含在聚合函數(shù)中。我們可以將GroupBy操作想象成如下的一個(gè)過(guò)程,首先系統(tǒng)根據(jù)SELECT語(yǔ)句得到一個(gè)結(jié)果集,如最開(kāi)始的那個(gè)水果、出產(chǎn)國(guó)家、單價(jià)的一個(gè)詳細(xì)表。然后根據(jù)分組字段,將具有相同分組字段的記錄歸并成了一條記錄。這個(gè)時(shí)候剩下的那些不存在于GroupBy語(yǔ)句后面作為分組依據(jù)的字段就有可能出現(xiàn)多個(gè)值,但是目前一種分組情況只有一條記錄,一個(gè)數(shù)據(jù)格是無(wú)法放入多個(gè)數(shù)值的,所以這里就需要通過(guò)一定的處理將這些多值的列轉(zhuǎn)化成單值,然后將其放在對(duì)應(yīng)的數(shù)據(jù)格中,那么完成這個(gè)步驟的就是聚合函數(shù)。這就是為什么這些函數(shù)叫聚合函數(shù)(aggregatefunctions)了。
2.2GroupByAll[expressions]:
GroupByAll+分組字段,這個(gè)和前面提到的GroupBy[Expressions]的形式多了一個(gè)關(guān)鍵字ALL。這個(gè)關(guān)鍵字只有在使用了where語(yǔ)句的,且where條件篩選掉了一些組的情況才可以看出效果。在SQLServer201*的聯(lián)機(jī)幫助中,對(duì)于GroupByAll是這樣進(jìn)行描述的:
作者:mnmnm669
201*-4-1418:46回復(fù)此發(fā)言
2SQL語(yǔ)句:GroupBy總結(jié)如果使用ALL關(guān)鍵字,那么查詢(xún)結(jié)果將包括由GROUPBY子句產(chǎn)生的所有組,即使某些組沒(méi)有符合搜索條件的行。沒(méi)有ALL關(guān)鍵字,包含GROUPBY子句的SELECT語(yǔ)句將不顯示沒(méi)有符合條件的行的組。其中有這么一句話(huà)“如果使用ALL關(guān)鍵字,那么查詢(xún)結(jié)果將包含由GroupBy子句產(chǎn)生的所有組...沒(méi)有ALL關(guān)鍵字,那么不顯示不符合條件的行組!边@句話(huà)聽(tīng)起來(lái)好像挺耳熟的,對(duì)了,好像和LEFTJOIN和RIGHTJOIN有點(diǎn)像。其實(shí)這里是類(lèi)比LEFTJOIN來(lái)進(jìn)行理解的。還是基于如下這樣一個(gè)數(shù)據(jù)集:FruitNameProductPlacePriceAppleChina$1.1AppleJapan$2.1AppleUSA$2.5OrangeChina$0.8BananaChina$3.1PeachUSA$3.
首先我們不使用帶ALL關(guān)鍵字的GroupBy語(yǔ)句:
SELECTCOUNT(*)AS水果種類(lèi),ProductPlaceAS出產(chǎn)國(guó)FROMT_TEST_FRUITINFO
WHERE(ProductPlace"Japan")GROUPBYProductPlace
那么在最后結(jié)果中由于Japan不符合where語(yǔ)句,所以分組結(jié)果中將不會(huì)出現(xiàn)Japan。
現(xiàn)在我們加入ALL關(guān)鍵字:
SELECTCOUNT(*)AS水果種類(lèi),ProductPlaceAS出產(chǎn)國(guó)FROMT_TEST_FRUITINFO
WHERE(ProductPlace"Japan")GROUPBYALLProductPlace
重新運(yùn)行后,我們可以看到Japan的分組,但是對(duì)應(yīng)的“水果種類(lèi)”不會(huì)進(jìn)行真正的統(tǒng)計(jì),聚合函數(shù)會(huì)根據(jù)返回值的類(lèi)型用默認(rèn)值0或者NULL來(lái)代替聚合函數(shù)的返回值。
2.3GROUPBY[Expressions]WITHCUBE|ROLLUP:
首先需要說(shuō)明的是GroupByAll語(yǔ)句是不能和CUBE和ROLLUP關(guān)鍵字一起使用的。
首先先說(shuō)說(shuō)CUBE關(guān)鍵字,以下是SQLServer201*聯(lián)機(jī)幫助中的說(shuō)明:
指定在結(jié)果集內(nèi)不僅包含由GROUPBY提供的正常行,還包含匯總行。在結(jié)果集內(nèi)返回每個(gè)可能的組和子組組合的GROUPBY匯總行。GROUPBY匯總行在結(jié)果中顯示為NULL,但可用來(lái)表示所有值。使用GROUPING函數(shù)確定結(jié)果集內(nèi)的空值是否是GROUPBY匯總值。
結(jié)果集內(nèi)的匯總行數(shù)取決于GROUPBY子句內(nèi)包含的列數(shù)。GROUPBY子句中的每個(gè)操作數(shù)(列)綁定在分組NULL下,并且分組適用于所有其它操作數(shù)(列)。由于CUBE返回每個(gè)可能的組和子組組合,因此不論指定分組列時(shí)所使用的是什么順序,行數(shù)都相同。
我們通常的GroupBy語(yǔ)句是按照其后所跟的所有字段進(jìn)行分組,而如果加入了CUBE關(guān)鍵字以后,那么系統(tǒng)將根據(jù)所有字段進(jìn)行分組的基礎(chǔ)上,還會(huì)通過(guò)對(duì)所有這些分組字段所有可能存在的組合形成的分組條件進(jìn)行分組計(jì)算。由于上面舉的例子過(guò)于簡(jiǎn)單,這里就再適合了,現(xiàn)在我們的數(shù)據(jù)集將換一個(gè)場(chǎng)景,一個(gè)表中包含人員的基本信息:?jiǎn)T工所在的部門(mén)編號(hào)(C_EMPLINFO_DEPTID)、員工性別(C_EMPLINFO_SEX)、員工姓名(C_EMPLINFO_NAME)等。那么我現(xiàn)在想知道每個(gè)部門(mén)各個(gè)性別的人數(shù),那么我們可以通過(guò)如下語(yǔ)句得到:SELECTC_EMPLINFO_DEPTID,C_EMPLINFO_SEX,COUNT(*)ASC_EMPLINFO_TOTALSTAFFNUMFROMT_PERSONNEL_EMPLINFOGROUPBYC_EMPLINFO_DEPTID,C_EMPLINFO_SEX但是如果我現(xiàn)在希望知道:1.所有部門(mén)有多少人(這里相當(dāng)于就不進(jìn)行分組了,因?yàn)檫@里已經(jīng)對(duì)員工的部門(mén)和性別沒(méi)有做任何限制了,但是這的確也是一種分組條件的組合方式);2.每種性別有多人(這里實(shí)際上是僅僅根據(jù)性別(C_EMPLINFO_SEX)進(jìn)行分組);
擴(kuò)展閱讀:[數(shù)據(jù)庫(kù)]簡(jiǎn)單SQL語(yǔ)句總結(jié)
SQL關(guān)系型數(shù)據(jù)庫(kù)系統(tǒng)簡(jiǎn)單SQL語(yǔ)句總結(jié)
[數(shù)據(jù)庫(kù)]簡(jiǎn)單SQL語(yǔ)句總結(jié)
全篇以學(xué)生成績(jī)的管理為例描述。1.在查詢(xún)結(jié)果中顯示列名:
a.用as關(guān)鍵字:selectnameas"姓名"fromstudentsorderbyageb.直接表示:selectname"姓名"fromstudentsorderbyage2.精確查找:
a.用in限定范圍:select*fromstudentswherenativein("湖南","四川")b.between...and:select*fromstudentswhereagebetween20and30c.“=”:select*fromstudentswherename="李山"
d.like:select*fromstudentswherenamelike"李%"(注意查詢(xún)條件中有“%”,則說(shuō)明是部分匹配,而且還有先后信息在里面,即查找以“李”開(kāi)頭的匹配項(xiàng)。所以若查詢(xún)有“李”的所有對(duì)象,應(yīng)該命令:"%李%";若是第二個(gè)字為李,則應(yīng)為"_李%"或"_李"或"_李_"。)
e.[]匹配檢查符:select*fromcourseswherecnolike"[AC]%"(表示或的關(guān)系,與"in(...)"類(lèi)似,而且"[]"可以表示范圍,如:select*fromcourseswherecnolike"[A-C]%")
3.對(duì)于時(shí)間類(lèi)型變量的處理
a.smalldatetime:直接按照字符串處理的方式進(jìn)行處理,例如:
select*fromstudentswherebirth>="1980-1-1"andbirthSQL關(guān)系型數(shù)據(jù)庫(kù)系統(tǒng)簡(jiǎn)單SQL語(yǔ)句總結(jié)
groupbygender(查看男女學(xué)生各有多少)
注意:從哪種角度分組就從哪列"groupby"
對(duì)于多重分組,只需將分組規(guī)則羅列。比如查詢(xún)各屆各專(zhuān)業(yè)的男女同學(xué)人數(shù),那么分組規(guī)則有:屆別(grade)、專(zhuān)業(yè)(mno)和性別(gender),所以有"groupbygrade,mno,gender"selectgrade,mno,gender,count(*)fromstudents
groupbygrade,mno,gender
通常group還和having聯(lián)用,比如查詢(xún)1門(mén)課以上不及格的學(xué)生,則按學(xué)號(hào)(sno)分類(lèi)有:selectsno,count(*)fromgradeswheremark1
6.UNION聯(lián)合合并查詢(xún)結(jié)果,如:SELECT*FROMstudentsWHEREnamelike張%UNION[ALL]
SELECT*FROMstudentsWHEREnamelike李%
7.多表查詢(xún)a.內(nèi)連接
selectg.sno,s.name,c.coursename
fromgradesgJOINstudentssONg.sno=s.snoJOINcoursescONg.cno=c.cno(注意可以引用別名)b.外連接
2SQL關(guān)系型數(shù)據(jù)庫(kù)系統(tǒng)簡(jiǎn)單SQL語(yǔ)句總結(jié)
b1.左連接
selectcourses.cno,max(coursename),count(sno)
fromcoursesLEFTJOINgradesONcourses.cno=grades.cnogroupbycourses.cno
左連接特點(diǎn):顯示全部左邊表中的所有項(xiàng)目,即使其中有些項(xiàng)中的數(shù)據(jù)未填寫(xiě)完全。左外連接返回那些存在于左表而右表中卻沒(méi)有的行,再加上內(nèi)連接的行。b2.右連接與左連接類(lèi)似b3.全連接
selectsno,name,major
fromstudentsFULLJOINmajorsONstudents.mno=majors.mno兩邊表中的內(nèi)容全部顯示c.自身連接
selectc1.cno,c1.coursename,c1.pno,c2.coursenamefromcoursesc1,coursesc2wherec1.pno=c2.cno采用別名解決問(wèn)題。d.交叉連接
selectlastname+firstnamefromlastnameCROSSJOINfirstanme相當(dāng)于做笛卡兒積
8.嵌套查詢(xún)
a.用關(guān)鍵字IN,如查詢(xún)李山的同鄉(xiāng):select*fromstudents
wherenativein(selectnativefromstudentswherename=李山)b.使用關(guān)鍵字EXIST,比如,下面兩句是等價(jià)的:select*fromstudents
wheresnoin(selectsnofromgradeswherecno=B2)
SQL關(guān)系型數(shù)據(jù)庫(kù)系統(tǒng)簡(jiǎn)單SQL語(yǔ)句總結(jié)
select*fromstudentswhereexists(select*fromgradeswhere
grades.sno=students.snoANDcno=B2)
9.關(guān)于排序order
a.對(duì)于排序order,有兩種方法:asc升序和desc降序
b.對(duì)于排序order,可以按照查詢(xún)條件中的某項(xiàng)排列,而且這項(xiàng)可用數(shù)字表示,如:selectsno,count(*),avg(mark)fromgradesgroupbysnohavingavg(mark)>85orderby310.其他
a.對(duì)于有空格的識(shí)別名稱(chēng),應(yīng)該用"[]"括住。
b.對(duì)于某列中沒(méi)有數(shù)據(jù)的特定查詢(xún)可以用null判斷,如selectsno,coursenofromgradeswheremarkISNULL
c.注意區(qū)分在嵌套查詢(xún)中使用的any與all的區(qū)別,any相當(dāng)于邏輯運(yùn)算“||”而all則相當(dāng)于邏輯運(yùn)算“&&”
d.注意在做否定意義的查詢(xún)是小心進(jìn)入陷阱:如,沒(méi)有選修B2課程的學(xué)生:selectstudents.*fromstudents,grades
wherestudents.sno=grades.sno
ANDgrades.cnoB2上面的查詢(xún)方式是錯(cuò)誤的,正確方式見(jiàn)下方:select*fromstudents
wherenotexists(select*fromgradeswheregrades.sno=students.snoANDcno="B2")
SQL關(guān)系型數(shù)據(jù)庫(kù)系統(tǒng)簡(jiǎn)單SQL語(yǔ)句總結(jié)
11.關(guān)于有難度多重嵌套查詢(xún)的解決思想:如,選修了全部課程的學(xué)生:select*fromstudents
wherenotexists(select*fromcourseswhereNOTEXISTS(select*fromgrades
wheresno=students.snoANDcno=courses.cno))
最外一重:從學(xué)生表中選,排除那些有課沒(méi)選的。用notexist。由于討論對(duì)象是課程,所以第二重查詢(xún)從course表中找,排除那些選了課的即可。
友情提示:本文中關(guān)于《SQL語(yǔ)句--Group By總結(jié)》給出的范例僅供您參考拓展思維使用,SQL語(yǔ)句--Group By總結(jié):該篇文章建議您自主創(chuàng)作。
來(lái)源:網(wǎng)絡(luò)整理 免責(zé)聲明:本文僅限學(xué)習(xí)分享,如產(chǎn)生版權(quán)問(wèn)題,請(qǐng)聯(lián)系我們及時(shí)刪除。