廢話不多說了,直接給大家貼代碼了,具體代碼如下所示:
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 一般用到的就是“每這個字” 例如說明現在有一個這樣的表:每個部門有多少人 就要用到分組的技術 select DepartmentID as '部門名稱' , COUNT (*) as '個數' from BasicDepartment group by DepartmentID --這個就是使用了group by +字段 進行了分組,其中我們就可以理解為我們按照了部門的名稱ID --DepartmentID將數據集進行了分組;然后再進行各個組的統計數據分別有多少; --如果不用count(*) 而用類似下面的語法 select DepartmentID,DepartmentName from BasicDepartment group by DepartmentID --將會出現錯誤 --選擇列表中的列 'BasicDepartment.DepartmentName' 無效,因為該列沒有包含在聚合函數或 GROUP BY 子句中。 這就是我們需要注意的一點,如果在返回集字段中,這些字段 要么就要包含在 Group By 語句的后面,作為分組的依據; 要么就要被包含在聚合函數中,作為分組的依據; --出現的錯誤詳解:咱們看看group by 的執行的過程,先執行select 的操作返回一個程序集, --然后去執行分組的操作,這時候他將根據group by 后面的字段 --進行分組,并且將相同的字段并稱一列數據,如果group by 后面沒有這個字段的話就要分成好多的數據。 --但是分組就只能將相同的數據分成兩列數據,而一列中又只能放入一個字段,所以那些沒有進行分組的 --數據系統不知道將數據放入哪里,所以就出現此錯誤 --目前一種分組情況只有一條記錄,一個數據格是無法放入多個數值的, --所以這里就需要通過一定的處理將這些多值的列轉化成單值,然后將其放在對應的 --數據格中,那么完成這個步驟的就是聚合函數。這就是為什么這些函數叫聚合函數(aggregate functions)了 --group by all語法解析: --如果使用 ALL 關鍵字,那么查詢結果將包括由 GROUP BY 子句產生的所有組,即使某些組沒有符合搜索條件的行。 --沒有 ALL 關鍵字,包含 GROUP BY 子句的 SELECT 語句將不顯示沒有符合條件的行的組。 select DepartmentID,DepartmentName as '部門名稱' , COUNT (*) as '個數' from BasicDepartment group by all DepartmentID,DepartmentName ========================================================================================================== --group by 和having 解釋:前提必須了解sql語言中一種特殊的函數:聚合函數, 例如 SUM , COUNT , MAX , AVG 等。這些函數和其它函數的根本區別就是它們一般作用在多條記錄上。 having 是分組( group by )后的篩選條件,分組后的數據組內再篩選 where 則是在分組前篩選 where 子句中不能使用聚集函數,而 having 子句中可以,所以在集合函數中加上了 HAVING 來起到測試查詢結果是否符合條件的作用。 即 having 子句的適用場景是可以使用聚合函數 having 子句限制的是組,而不是行 having 子句中的每一個元素也必須出現在 select 列表中。有些數據庫例外,如oracle 當同時含有 where 子句、 group by 子句 、 having 子句及聚集函數時,執行順序如下: 執行 where 子句查找符合條件的數據; 使用 group by 子句對數據進行分組;對 group by 子句形成的組運行聚集函數計算每一組的值;最后用 having 子句去掉不符合條件的組 ex: 顯示每個地區的總人口數和總面積.僅顯示那些面積超過1000000的地區。 SELECT region, SUM (population), SUM (area) FROM bbc GROUP BY region HAVING SUM (area)>1000000 在這里,我們不能用 where 來篩選超過1000000的地區,因為表中不存在這樣一條記錄。( where 子句中不能使用聚集函數) 相反, HAVING 子句可以讓我們篩選成組后的各組數據 ex: create TABLE Table1 ( ID int identity(1,1) primary key NOT NULL , classid int , sex varchar (10), age int , ) --添加測試多條數據 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) .......... 查詢每一個班級中年齡大于20,性別為男的人數至少為2個的情況 select COUNT (age) as '>20歲人數' ,classid from Table1 where sex= '男' group by classid having COUNT (age)>2 底下這個例子很好 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 這個表所描述的是4個學生對應每科學習成績的記錄,其中SNO(學生號)、PNO(課程名)、GRADE(成績)。 1、顯示90分以上學生的課程名和成績 //這是一個簡單的查詢,并沒有使用分組查詢 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、顯示每個學生的成績在90分以上的各有多少門 --進行分組顯示,并且按照where條件之后計數 SQL> select sno, count (*) from sc where grade>=90 group by sno; SNO COUNT (*) - --------- ---------- 3 2 1 1 3、這里我們并沒有使用 having 語句,接下來如果我們要評選三好學生,條件是至少有兩門課程在90分以上才能有資格, 列出有資格的學生號及90分以上的課程數。 //進行分組顯示,并且按照 where 條件之后計數,在根據 having 子句篩選分組 SQL> select sno, count (*) from sc where grade>=90 group by sno having count (*)>=2; SNO COUNT (*) ---------- ---------- 3 2 這個結果是我們想要的,它列出了具有評選三好學生資格的學生號,跟上一個例子比較之后,發現這是在分組后進行的子查詢。 4、學校評選先進學生,要求平均成績大于90分的學生都有資格,并且語文課必須在95分以上,請列出有資格的學生 //實際上,這個查詢先把語文大于95分的學生號提取出來,之后求平均值,分組顯示后根據 having 語句選出平均成績大于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、查詢比平均成績至少比學號是3的平均成績高的學生學號以及平均分數 // having 子句中可進行比較和子查詢 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