一:聚合函數
1. 聚合函數的介紹
聚合函數又叫組函數,通常是對表中的數據進行統計和計算,一般結合分組(group by)來使用,用於統計和計算分組數據。
常用的聚合函數:
- count(col): 表示求指定列的總行數
- max(col): 表示求指定列的最大值
- min(col): 表示求指定列的最小值
- sum(col): 表示求指定列的和
- avg(col): 表示求指定列的平均值
2. 求總行數
-- 返回非NULL數據的總行數. select count(height) from students; -- 返回總行數,包含null值記錄; select count(*) from students;
3. 求最大值
-- 查詢女生的編號最大值 select max(id) from students where gender = 2;
4. 求最小值
-- 查詢未刪除的學生最小編號 select min(id) from students where is_delete = 0;
5. 求和
-- 查詢男生的總身高 select sum(height) from students where gender = 1; -- 平均身高 select sum(height) / count(*) from students where gender = 1;
6. 求平均值
-- 求男生的平均身高, 聚合函數不統計null值,平均身高有誤 select avg(height) from students where gender = 1; -- 求男生的平均身高, 包含身高是null的 select avg(ifnull(height,0)) from students where gender = 1;
說明
- ifnull函數: 表示判斷指定字段的值是否為null,如果為空使用自己提供的值。
7. 聚合函數的特點
- 聚合函數默認忽略字段為null的記錄 要想列值為null的記錄也參與計算,必須使用ifnull函數對null值做替換。
二:分組函數
1. 分組查詢介紹
分組查詢就是將查詢結果按照指定字段進行分組,字段中數據相等的分為一組。
分組查詢基本的語法格式如下:
GROUP BY 列名 [HAVING 條件表達式] [WITH ROLLUP]
說明:
- 列名: 是指按照指定字段的值進行分組。
- HAVING 條件表達式: 用來過濾分組后的數據。
- WITH ROLLUP:在所有記錄的最后加上一條記錄,顯示select查詢時聚合函數的統計和計算結果
2. group by的使用
group by可用於單個字段分組,也可用於多個字段分組
mysql> select gender from students group by gender; +--------+ | gender | +--------+ | NULL | | ? | | ? | +--------+ 3 rows in set (0.00 sec) mysql> select name, gender from students group by name, gender; +----------+--------+ | name | gender | +----------+--------+ | lisi | ? | | peiqi | ? | | waang | NULL | | zhangsan | ? | | 平二 | ? | +----------+--------+ 5 rows in set (0.00 sec) mysql>
3. group by + group_concat()的使用
group_concat(字段名): 統計每個分組指定字段的信息集合,每個信息之間使用逗號進行分割
-- 根據gender字段進行分組, 查詢gender字段和分組的name字段信息 mysql> select gender,group_concat(name) from students group by gender; +--------+--------------------+ | gender | group_concat(name) | +--------+--------------------+ | NULL | waang | | ? | peiqi,zhangsan | | ? | lisi,平二 | +--------+--------------------+ 3 rows in set (0.00 sec)
4. group by + 聚合函數的使用
-- 統計不同性別的人的平均年齡 mysql> select gender,avg(age) from students group by gender; +--------+----------+ | gender | avg(age) | +--------+----------+ | NULL | 15.0000 | | ? | 9.0000 | | ? | 18.0000 | +--------+----------+ 3 rows in set (0.00 sec) -- 統計不同性別的人的個數 mysql> select gender,count(*) from students group by gender; +--------+----------+ | gender | count(*) | +--------+----------+ | NULL | 1 | | ? | 2 | | ? | 2 | +--------+----------+ 3 rows in set (0.00 sec) mysql>
5. group by + having的使用
having作用和where類似都是過濾數據的,但having是過濾分組數據的,只能用於group by
-- 根據gender字段進行分組,統計分組條數大於2的 mysql> select gender,count(*) from students group by gender having count(*)>=2; +--------+----------+ | gender | count(*) | +--------+----------+ | ? | 2 | | ? | 2 | +--------+----------+ 2 rows in set (0.00 sec)
6. group by + with rollup的使用
with rollup的作用是:在最后記錄后面新增一行,顯示select查詢時聚合函數的統計和計算結果
-- 根據gender字段進行分組,匯總總人數 mysql> select gender,count(*) from students group by gender with rollup; +--------+----------+ | gender | count(*) | +--------+----------+ | NULL | 1 | | ? | 2 | | ? | 2 | | NULL | 5 | +--------+----------+ 4 rows in set (0.00 sec) -- 根據gender字段進行分組,匯總所有人的年齡 mysql> select gender,group_concat(age) from students group by gender with rollup; +--------+-------------------+ | gender | group_concat(age) | +--------+-------------------+ | NULL | 15 | | ? | 0,18 | | ? | 18,18 | | NULL | 15,0,18,18,18 | +--------+-------------------+ 4 rows in set (0.00 sec) mysql>
三:連接查詢
1. 連接查詢的介紹
連接查詢可以實現多個表的查詢,當查詢的字段數據來自不同的表就可以使用連接查詢來完成。
連接查詢可以分為:
- 內連接查詢
- 左連接查詢
- 右連接查詢
- 自連接查詢
2. 內連接查詢
查詢兩個表中符合條件的共有記錄
內連接查詢效果圖:
內連接查詢語法格式:
select 字段 from 表1 inner join 表2 on 表1.字段1 = 表2.字段2
說明:
- inner join 就是內連接查詢關鍵字
- on 就是連接查詢條件
例1:使用內連接查詢學生表與班級表:

mysql> select * from class; +----+-------+---------------+ | id | title | student_count | +----+-------+---------------+ | 0 | 1班 | 20 | | 1 | 2班 | 30 | | 2 | 3班 | 32 | +----+-------+---------------+ 3 rows in set (0.00 sec) mysql> select * from students; +----+----------+------+--------+--------+ | id | name | age | height | gender | +----+----------+------+--------+--------+ | 1 | peiqi | 0 | NULL | ? | | 2 | waang | 15 | NULL | NULL | | 3 | zhangsan | 18 | 180.00 | ? | | 4 | lisi | 18 | 160.00 | ? | | 5 | 平二 | 18 | 160.00 | ? | +----+----------+------+--------+--------+ 5 rows in set (0.00 sec) mysql> select * from students as s inner join class as c on s.id=c.id; +----+-------+------+--------+--------+----+-------+---------------+ | id | name | age | height | gender | id | title | student_count | +----+-------+------+--------+--------+----+-------+---------------+ | 1 | peiqi | 0 | NULL | ? | 1 | 2班 | 30 | | 2 | waang | 15 | NULL | NULL | 2 | 3班 | 32 | +----+-------+------+--------+--------+----+-------+---------------+ 2 rows in set (0.00 sec) mysql>
3. 左連接查詢
以左表為主根據條件查詢右表數據,如果根據條件查詢右表數據不存在使用null值填充
左連接查詢效果圖:
左連接查詢語法格式:
select 字段 from 表1 left join 表2 on 表1.字段1 = 表2.字段2
說明:
- left join 就是左連接查詢關鍵字
- on 就是連接查詢條件
- 表1 是左表
- 表2 是右表
例1:使用左連接查詢學生表與班級表:

mysql> select * from students as s left join class as c on s.id=c.id; +----+----------+------+--------+--------+------+-------+---------------+ | id | name | age | height | gender | id | title | student_count | +----+----------+------+--------+--------+------+-------+---------------+ | 1 | peiqi | 0 | NULL | ? | 1 | 2班 | 30 | | 2 | waang | 15 | NULL | NULL | 2 | 3班 | 32 | | 3 | zhangsan | 18 | 180.00 | ? | NULL | NULL | NULL | | 4 | lisi | 18 | 160.00 | ? | NULL | NULL | NULL | | 5 | 平二 | 18 | 160.00 | ? | NULL | NULL | NULL | +----+----------+------+--------+--------+------+-------+---------------+ 5 rows in set (0.00 sec) mysql>
4. 右連接查詢
以右表為主根據條件查詢左表數據,如果根據條件查詢左表數據不存在使用null值填充
右連接查詢效果圖:
右連接查詢語法格式:
select 字段 from 表1 right join 表2 on 表1.字段1 = 表2.字段2
說明:
- right join 就是右連接查詢關鍵字
- on 就是連接查詢條件
- 表1 是左表
- 表2 是右表
例1:使用右連接查詢學生表與班級表:

mysql> select * from students as s right join class as c on s.id=c.id; +------+-------+------+--------+--------+----+-------+---------------+ | id | name | age | height | gender | id | title | student_count | +------+-------+------+--------+--------+----+-------+---------------+ | NULL | NULL | NULL | NULL | NULL | 0 | 1班 | 20 | | 1 | peiqi | 0 | NULL | ? | 1 | 2班 | 30 | | 2 | waang | 15 | NULL | NULL | 2 | 3班 | 32 | +------+-------+------+--------+--------+----+-------+---------------+ 3 rows in set (0.00 sec) mysql>
6. 自連接查詢
左表和右表是同一個表,根據連接查詢條件查詢兩個表中的數據。
自連接查詢的用法:
select c.id, c.title, c.pid, p.title from areas as c inner join areas as p on c.pid = p.id where p.title = '山西省';
說明:
- 自連接查詢必須對表起別名
7. 子查詢的介紹
在一個 select 語句中,嵌入了另外一個 select 語句, 那么被嵌入的 select 語句稱之為子查詢語句,外部那個select語句則稱為主查詢.
主查詢和子查詢的關系:
- 子查詢是嵌入到主查詢中
- 子查詢是輔助主查詢的,要么充當條件,要么充當數據源
- 子查詢是可以獨立存在的語句,是一條完整的 select 語句
7.2. 子查詢的使用
例1. 查詢大於平均年齡的學生:
select * from students where age > (select avg(age) from students);
例2. 查詢學生在班的所有班級名字:
select name from classes where id in (select cls_id from students where cls_id is not null);
例3. 查找年齡最大,身高最高的學生:
select * from students where (age, height) = (select max(age), max(height) from students);
四:外鍵約束查詢
1. 外鍵約束作用
外鍵約束:對外鍵字段的值進行更新和插入時會和引用表中字段的數據進行驗證,數據如果不合法則更新和插入會失敗,保證數據的有效性
2. 對於已經存在的字段添加外鍵約束
-- 為cls_id字段添加外鍵約束 alter table students add foreign key(cls_id) references classes(id);
3. 在創建數據表時設置外鍵約束
-- 創建學校表 create table school( id int not null primary key auto_increment, name varchar(10) ); -- 創建老師表 create table teacher( id int not null primary key auto_increment, name varchar(10), s_id int not null, foreign key(s_id) references school(id) );
4. 刪除外鍵約束
-- 需要先獲取外鍵約束名稱,該名稱系統會自動生成,可以通過查看表創建語句來獲取名稱 show create table teacher; -- 獲取名稱之后就可以根據名稱來刪除外鍵約束 alter table teacher drop foreign key 外鍵名;
分組和聚合函數的使用
1. 數據准備
-- 創建 "京東" 數據庫 create database jing_dong charset=utf8; -- 使用 "京東" 數據庫 use jing_dong; -- 創建一個商品goods數據表 create table goods( id int unsigned primary key auto_increment not null, name varchar(150) not null, cate_name varchar(40) not null, brand_name varchar(40) not null, price decimal(10,3) not null default 0, is_show bit not null default 1, is_saleoff bit not null default 0 ); -- 向goods表中插入數據 insert into goods values(0,'r510vc 15.6英寸筆記本','筆記本','華碩','3399',default,default); insert into goods values(0,'y400n 14.0英寸筆記本電腦','筆記本','聯想','4999',default,default); insert into goods values(0,'g150th 15.6英寸游戲本','游戲本','雷神','8499',default,default); insert into goods values(0,'x550cc 15.6英寸筆記本','筆記本','華碩','2799',default,default); insert into goods values(0,'x240 超極本','超級本','聯想','4880',default,default); insert into goods values(0,'u330p 13.3英寸超極本','超級本','聯想','4299',default,default); insert into goods values(0,'svp13226scb 觸控超極本','超級本','索尼','7999',default,default); insert into goods values(0,'ipad mini 7.9英寸平板電腦','平板電腦','蘋果','1998',default,default); insert into goods values(0,'ipad air 9.7英寸平板電腦','平板電腦','蘋果','3388',default,default); insert into goods values(0,'ipad mini 配備 retina 顯示屏','平板電腦','蘋果','2788',default,default); insert into goods values(0,'ideacentre c340 20英寸一體電腦 ','台式機','聯想','3499',default,default); insert into goods values(0,'vostro 3800-r1206 台式電腦','台式機','戴爾','2899',default,default); insert into goods values(0,'imac me086ch/a 21.5英寸一體電腦','台式機','蘋果','9188',default,default); insert into goods values(0,'at7-7414lp 台式電腦 linux )','台式機','宏碁','3699',default,default); insert into goods values(0,'z220sff f4f06pa工作站','服務器/工作站','惠普','4288',default,default); insert into goods values(0,'poweredge ii服務器','服務器/工作站','戴爾','5388',default,default); insert into goods values(0,'mac pro專業級台式電腦','服務器/工作站','蘋果','28888',default,default); insert into goods values(0,'hmz-t3w 頭戴顯示設備','筆記本配件','索尼','6999',default,default); insert into goods values(0,'商務雙肩背包','筆記本配件','索尼','99',default,default); insert into goods values(0,'x3250 m4機架式服務器','服務器/工作站','ibm','6888',default,default); insert into goods values(0,'商務雙肩背包','筆記本配件','索尼','99',default,default);
表結構說明:
- id 表示主鍵 自增
- name 表示商品名稱
- cate_name 表示分類名稱
- brand_name 表示品牌名稱
- price 表示價格
- is_show 表示是否顯示
- is_saleoff 表示是否售完
2. SQL語句演練
--查詢類型cate_name為 '超極本' 的商品名稱、價格 select name,price from goods where cate_name = '超級本'; --顯示商品的分類 select cate_name from goods group by cate_name; --求所有電腦產品的平均價格,並且保留兩位小數 select round(avg(price),2) as avg_price from goods; --顯示每種商品的平均價格 select cate_name,avg(price) from goods group by cate_name; --查詢每種類型的商品中 最貴、最便宜、平均價、數量 select cate_name,max(price),min(price),avg(price),count(*) from goods group by cate_name; --查詢所有價格大於平均價格的商品,並且按價格降序排序 select id,name,price from goods where price > (select round(avg(price),2) as avg_price from goods) order by price desc;