廢話不多說(shuō)了,直接給大家貼代碼了,具體代碼如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
--sql中的 where 、group by 和 having 用法解析 --如果要用到group by 一般用到的就是“每這個(gè)字” 例如說(shuō)明現(xiàn)在有一個(gè)這樣的表:每個(gè)部門(mén)有多少人 就要用到分組的技術(shù) select DepartmentID as '部門(mén)名稱' , COUNT (*) as '個(gè)數(shù)' from BasicDepartment group by DepartmentID --這個(gè)就是使用了group by +字段 進(jìn)行了分組,其中我們就可以理解為我們按照了部門(mén)的名稱ID --DepartmentID將數(shù)據(jù)集進(jìn)行了分組;然后再進(jìn)行各個(gè)組的統(tǒng)計(jì)數(shù)據(jù)分別有多少; --如果不用count(*) 而用類似下面的語(yǔ)法 select DepartmentID,DepartmentName from BasicDepartment group by DepartmentID --將會(huì)出現(xiàn)錯(cuò)誤 --選擇列表中的列 'BasicDepartment.DepartmentName' 無(wú)效,因?yàn)樵摿袥](méi)有包含在聚合函數(shù)或 GROUP BY 子句中。 這就是我們需要注意的一點(diǎn),如果在返回集字段中,這些字段 要么就要包含在 Group By 語(yǔ)句的后面,作為分組的依據(jù); 要么就要被包含在聚合函數(shù)中,作為分組的依據(jù); --出現(xiàn)的錯(cuò)誤詳解:咱們看看group by 的執(zhí)行的過(guò)程,先執(zhí)行select 的操作返回一個(gè)程序集, --然后去執(zhí)行分組的操作,這時(shí)候他將根據(jù)group by 后面的字段 --進(jìn)行分組,并且將相同的字段并稱一列數(shù)據(jù),如果group by 后面沒(méi)有這個(gè)字段的話就要分成好多的數(shù)據(jù)。 --但是分組就只能將相同的數(shù)據(jù)分成兩列數(shù)據(jù),而一列中又只能放入一個(gè)字段,所以那些沒(méi)有進(jìn)行分組的 --數(shù)據(jù)系統(tǒng)不知道將數(shù)據(jù)放入哪里,所以就出現(xiàn)此錯(cuò)誤 --目前一種分組情況只有一條記錄,一個(gè)數(shù)據(jù)格是無(wú)法放入多個(gè)數(shù)值的, --所以這里就需要通過(guò)一定的處理將這些多值的列轉(zhuǎn)化成單值,然后將其放在對(duì)應(yīng)的 --數(shù)據(jù)格中,那么完成這個(gè)步驟的就是聚合函數(shù)。這就是為什么這些函數(shù)叫聚合函數(shù)(aggregate functions)了 --group by all語(yǔ)法解析: --如果使用 ALL 關(guān)鍵字,那么查詢結(jié)果將包括由 GROUP BY 子句產(chǎn)生的所有組,即使某些組沒(méi)有符合搜索條件的行。 --沒(méi)有 ALL 關(guān)鍵字,包含 GROUP BY 子句的 SELECT 語(yǔ)句將不顯示沒(méi)有符合條件的行的組。 select DepartmentID,DepartmentName as '部門(mén)名稱' , COUNT (*) as '個(gè)數(shù)' from BasicDepartment group by all DepartmentID,DepartmentName ========================================================================================================== --group by 和having 解釋:前提必須了解sql語(yǔ)言中一種特殊的函數(shù):聚合函數(shù), 例如 SUM , COUNT , MAX , AVG 等。這些函數(shù)和其它函數(shù)的根本區(qū)別就是它們一般作用在多條記錄上。 having 是分組( group by )后的篩選條件,分組后的數(shù)據(jù)組內(nèi)再篩選 where 則是在分組前篩選 where 子句中不能使用聚集函數(shù),而 having 子句中可以,所以在集合函數(shù)中加上了 HAVING 來(lái)起到測(cè)試查詢結(jié)果是否符合條件的作用。 即 having 子句的適用場(chǎng)景是可以使用聚合函數(shù) having 子句限制的是組,而不是行 having 子句中的每一個(gè)元素也必須出現(xiàn)在 select 列表中。有些數(shù)據(jù)庫(kù)例外,如oracle 當(dāng)同時(shí)含有 where 子句、 group by 子句 、 having 子句及聚集函數(shù)時(shí),執(zhí)行順序如下: 執(zhí)行 where 子句查找符合條件的數(shù)據(jù); 使用 group by 子句對(duì)數(shù)據(jù)進(jìn)行分組;對(duì) group by 子句形成的組運(yùn)行聚集函數(shù)計(jì)算每一組的值;最后用 having 子句去掉不符合條件的組 ex: 顯示每個(gè)地區(qū)的總?cè)丝跀?shù)和總面積.僅顯示那些面積超過(guò)1000000的地區(qū)。 SELECT region, SUM (population), SUM (area) FROM bbc GROUP BY region HAVING SUM (area)>1000000 在這里,我們不能用 where 來(lái)篩選超過(guò)1000000的地區(qū),因?yàn)楸碇胁淮嬖谶@樣一條記錄。( where 子句中不能使用聚集函數(shù)) 相反, HAVING 子句可以讓我們篩選成組后的各組數(shù)據(jù) ex: create TABLE Table1 ( ID int identity(1,1) primary key NOT NULL , classid int , sex varchar (10), age int , ) --添加測(cè)試多條數(shù)據(jù) Insert into Table1 values (1, '男' ,20) Insert into Table1 values (2, '女' ,22) Insert into Table1 values (3, '男' ,23) Insert into Table1 values (4, '男' ,22) Insert into Table1 values (1, '男' ,24) .......... 查詢每一個(gè)班級(jí)中年齡大于20,性別為男的人數(shù)至少為2個(gè)的情況 select COUNT (age) as '>20歲人數(shù)' ,classid from Table1 where sex= '男' group by classid having COUNT (age)>2 底下這個(gè)例子很好 SQL> select * from sc; SNO PNO GRADE ---------- ----- ---------- YW 95 SX 98 YY 90 YW 89 SX 91 YY 92 YW 85 SX 88 YY 96 YW 95 SX 89 YY 88 這個(gè)表所描述的是4個(gè)學(xué)生對(duì)應(yīng)每科學(xué)習(xí)成績(jī)的記錄,其中SNO(學(xué)生號(hào))、PNO(課程名)、GRADE(成績(jī))。 1、顯示90分以上學(xué)生的課程名和成績(jī) //這是一個(gè)簡(jiǎn)單的查詢,并沒(méi)有使用分組查詢 SQL> select sno,pno,grade from sc where grade>=90; SNO PNO GRADE ---------- ----- ---------- YW 95 SX 98 YY 90 SX 91 YY 92 YY 96 YW 95 2、顯示每個(gè)學(xué)生的成績(jī)?cè)?0分以上的各有多少門(mén) --進(jìn)行分組顯示,并且按照where條件之后計(jì)數(shù) SQL> select sno, count (*) from sc where grade>=90 group by sno; SNO COUNT (*) - --------- ---------- 3 2 1 1 3、這里我們并沒(méi)有使用 having 語(yǔ)句,接下來(lái)如果我們要評(píng)選三好學(xué)生,條件是至少有兩門(mén)課程在90分以上才能有資格, 列出有資格的學(xué)生號(hào)及90分以上的課程數(shù)。 //進(jìn)行分組顯示,并且按照 where 條件之后計(jì)數(shù),在根據(jù) having 子句篩選分組 SQL> select sno, count (*) from sc where grade>=90 group by sno having count (*)>=2; SNO COUNT (*) ---------- ---------- 3 2 這個(gè)結(jié)果是我們想要的,它列出了具有評(píng)選三好學(xué)生資格的學(xué)生號(hào),跟上一個(gè)例子比較之后,發(fā)現(xiàn)這是在分組后進(jìn)行的子查詢。 4、學(xué)校評(píng)選先進(jìn)學(xué)生,要求平均成績(jī)大于90分的學(xué)生都有資格,并且語(yǔ)文課必須在95分以上,請(qǐng)列出有資格的學(xué)生 //實(shí)際上,這個(gè)查詢先把語(yǔ)文大于95分的學(xué)生號(hào)提取出來(lái),之后求平均值,分組顯示后根據(jù) having 語(yǔ)句選出平均成績(jī)大于90的 SQL> select sno, avg (grade) from sc where SNO IN ( SELECT SNO FROM SC WHERE GRADE>=95 AND PNO= 'YW' ) group by sno having avg (grade)>=90; SNO AVG (GRADE) ---------- ---------- 94.3333333 90.6666667 5、查詢比平均成績(jī)至少比學(xué)號(hào)是3的平均成績(jī)高的學(xué)生學(xué)號(hào)以及平均分?jǐn)?shù) // having 子句中可進(jìn)行比較和子查詢 SQL> select sno, avg (grade) from sc group by sno having avg (grade) > ( select avg (grade) from sc where sno=3); |
原文鏈接:http://www.cnblogs.com/gqs92/archive/2017/04/26/6767973.html