MySQL表聚合與聯(lián)合查詢(xún)的實(shí)現(xiàn)
一. 聚合查詢(xún)
1.1 聚合函數(shù)
一般情況下,我們需要的聚合數(shù)據(jù)(總和,平均數(shù),最大最小值等)并不總是存儲(chǔ)在表中。 但是,可以通過(guò)執(zhí)行存儲(chǔ)數(shù)據(jù)的計(jì)算來(lái)獲取它。
MySQL提供了許多聚合函數(shù),包括AVG,COUNT,SUM,MIN,MAX等。除COUNT函數(shù)外,其它聚合函數(shù)在執(zhí)行計(jì)算時(shí)會(huì)忽略NULL值 , 同時(shí) , 聚合函數(shù)不允許嵌套使用 .
| 函數(shù) | 說(shuō)明 |
|---|---|
| count(列名或表達(dá)式) | 返回查詢(xún)到的數(shù)據(jù)的個(gè)數(shù) |
| sum(列名或表達(dá)式) | 返回查詢(xún)到的數(shù)據(jù)的和, (不是數(shù)字沒(méi)有意義) |
| avg(列名或表達(dá)式) | 返回查詢(xún)到的數(shù)據(jù)的平均值 |
| max(列名或表達(dá)式) | 返回查詢(xún)到的數(shù)據(jù)的最大值 |
| min(列名或表達(dá)式) | 返回查詢(xún)到的數(shù)據(jù)的最小值 |
以上的聚合函數(shù)可以在列名和表達(dá)式之前加上
distinct, 先對(duì)查詢(xún)到的數(shù)據(jù)進(jìn)行去重, 再進(jìn)行計(jì)算
下面,我們將創(chuàng)建一組示例數(shù)據(jù),對(duì)以上的聚合函數(shù)進(jìn)行演示,
--- 創(chuàng)建學(xué)生成績(jī)表
mysql> create table exam(
-> id int primary key comment '學(xué)號(hào)',
-> name varchar(20) comment '學(xué)生姓名',
-> email varchar(50) not null comment '電子郵箱',
-> chinese decimal(4,1) comment '語(yǔ)文成績(jī)',
-> english decimal(4,1) comment '英語(yǔ)成績(jī)',
-> math decimal(4,1) comment'數(shù)學(xué)成績(jī)'
-> );
Query OK, 0 rows affected (0.02 sec)
--- 插入學(xué)生成績(jī)數(shù)據(jù)
mysql> insert into exam values(202301,'張華','123452@163.com',69,112,110),
-> (202302,'李三','1452563@163.com',115.5,120,89),
-> (202303,'宋七','36215465@qq.com',110,113,66),
-> (202304,'王五','15547522@163.com',89,65,78),
-> (202305,'趙四','15623355@163.com',90,112,130),
-> (202306,'李八','18625222@163.com',null,null,null);
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0
---學(xué)生成績(jī)表結(jié)構(gòu)
mysql> desc exam;
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| email | varchar(50) | NO | | NULL | |
| chinese | decimal(4,1) | YES | | NULL | |
| english | decimal(4,1) | YES | | NULL | |
| math | decimal(4,1) | YES | | NULL | |
+---------+--------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
--- 數(shù)據(jù)詳表
mysql> select * from exam;
+--------+------+------------------+---------+---------+-------+
| id | name | email | chinese | english | math |
+--------+------+------------------+---------+---------+-------+
| 202301 | 張華 | 123452@163.com | 69.0 | 112.0 | 110.0 |
| 202302 | 李三 | 1452563@163.com | 115.5 | 120.0 | 89.0 |
| 202303 | 宋七 | 36215465@qq.com | 110.0 | 113.0 | 66.0 |
| 202304 | 王五 | 15547522@163.com | 89.0 | 65.0 | 78.0 |
| 202305 | 趙四 | 15623355@163.com | 90.0 | 112.0 | 130.0 |
| 202306 | 李八 | 18625222@163.com | NULL | NULL | NULL |
+--------+------+------------------+---------+---------+-------+
6 rows in set (0.01 sec)count()函數(shù)
使用 count()函數(shù) 可以返回?cái)?shù)據(jù)表中的行數(shù) , 允許對(duì)表中所有符合特定條件的所有行進(jìn)行計(jì)數(shù) .
#計(jì)算表中的總行數(shù) mysql> select count(*) from exam; +----------+ | count(*) | +----------+ | 6 | +----------+ 1 row in set (0.01 sec #計(jì)算表中chinese中的總行數(shù) mysql> select count(math) from exam; +-------------+ | count(math) | +-------------+ | 5 | +-------------+ 1 row in set (0.00 sec) #計(jì)算表中english列的總行數(shù),并去重 mysql> select count(distinct english) from exam; +-------------------------+ | count(distinct english) | +-------------------------+ | 4 | +-------------------------+ 1 row in set (0.01 sec)
COUNT(*)函數(shù)計(jì)算包含NULL和非NULL值的行,即:所有行 , 而count (列名) 進(jìn)行計(jì)算時(shí) , 不會(huì)將值為NULL的行計(jì)算在內(nèi), 即所有的非空行 . count(distinct 列名) 則會(huì)返回不包含空值的唯一行數(shù) .
結(jié)合where語(yǔ)句進(jìn)行使用
#查詢(xún)exam表當(dāng)中, 英語(yǔ)成績(jī)?yōu)?12的人數(shù) mysql> select count(english) from exam where english = 112; +----------------+ | count(english) | +----------------+ | 2 | +----------------+ 1 row in set (0.00 sec)
sum()函數(shù)
SUM()函數(shù)返回一組值的總和,SUM()函數(shù)忽略NULL值。如果找不到匹配行,則SUM()函數(shù)返回NULL值。
#計(jì)算數(shù)學(xué)成績(jī)的總和, 并命名為emath mysql> select sum(math) as emath from exam; +-------+ | emath | +-------+ | 473.0 | +-------+ 1 row in set (0.00 sec) #計(jì)算英語(yǔ)成績(jī)低于120分的成績(jī)總和 mysql> select sum(english) from exam where english < 120; +--------------+ | sum(english) | +--------------+ | 402.0 | +--------------+ 1 row in set (0.00 sec)
avg()函數(shù)
AVG()函數(shù)計(jì)算一組值的平均值。 它計(jì)算過(guò)程中是忽略NULL值的 , 使用 avg() 函數(shù)可以的到 一組數(shù)據(jù)的平均值 .
# 計(jì)算所有同學(xué)的語(yǔ)文成績(jī)的平均值 mysql> select avg(chinese) from exam; +--------------+ | avg(chinese) | +--------------+ | 94.70000 | +--------------+ 1 row in set (0.03 sec) #計(jì)算總分的平均分 mysql> select avg(math+chinese+english) as 總均分 from exam; +-----------+ | 總均分 | +-----------+ | 293.70000 | +-----------+ 1 row in set (0.00 sec)
MAX()函數(shù)
MAX()函數(shù)返回一組值中的最大值。MAX()函數(shù)在許多查詢(xún)中非常方便,例如查找最大數(shù)量,最昂貴的產(chǎn)品以及客戶(hù)的最大付款數(shù)等 .
# 查詢(xún)總分最高的同學(xué)總分 mysql> select max(math+english+chinese) as 總成績(jī) from exam; +--------+ | 總成績(jī) | +--------+ | 332.0 | +--------+ 1 row in set (0.00 sec) #查詢(xún)單科英語(yǔ)成績(jī)的最高分的姓名 mysql> select max(english) from exam; +--------------+ | max(english) | +--------------+ | 120.0 | +--------------+ 1 row in set (0.00 sec)
不使用
max()函數(shù)的情況 , 也可以使用order by對(duì)數(shù)據(jù)集進(jìn)行降序,并使用limit字句對(duì)結(jié)果集進(jìn)行降序排序
mysql> select (chinese+math+english) as total from exam order by total desc limit 1; +-------+ | total | +-------+ | 332.0 | +-------+ 1 row in set (0.00 sec)
如果要找到總成績(jī)最高的同學(xué)的全部信息 , 需要使用子查詢(xún)進(jìn)行
# 查詢(xún)總成績(jī)最高的同學(xué)信息
mysql> select *
-> from exam
-> where chinese+math+english = (select max(chinese+math+english)
-> from exam
-> );
+--------+------+------------------+---------+---------+-------+
| id | name | email | chinese | english | math |
+--------+------+------------------+---------+---------+-------+
| 202305 | 趙四 | 15623355@163.com | 90.0 | 112.0 | 130.0 |
+--------+------+------------------+---------+---------+-------+
1 row in set (0.00 sec)Min()函數(shù)
Min()函數(shù)用于返回一組值當(dāng)中的最小值 , 通常用于 查詢(xún)一組數(shù)據(jù)當(dāng)中最小的值 , 如 最小單價(jià), 最小分?jǐn)?shù) 等 , 和 max() 函數(shù)的用法類(lèi)似 。
# 查詢(xún)最小的總分
mysql> select min(math + english + chinese) as total from exam;
+-------+
| total |
+-------+
| 232.0 |
+-------+
1 row in set (0.00 sec)
#查詢(xún)最小總分的全部信息
mysql> select * from exam
where chinese+english+math = (select min(math + english + chinese) as total from exam);
+--------+------+------------------+---------+---------+------+
| id | name | email | chinese | english | math |
+--------+------+------------------+---------+---------+------+
| 202304 | 王五 | 15547522@163.com | 89.0 | 65.0 | 78.0 |
+--------+------+------------------+---------+---------+------+
1 row in set (0.00 sec)MySQL 當(dāng)中除了一些常用的聚合函數(shù)外 , 還包括一些字符串函數(shù) , 日期時(shí)間函數(shù) , 控制流函數(shù)等 , 下面再列舉一些比較常見(jiàn)的其他函數(shù) .
IFNULL函數(shù)
IFNULL函數(shù) 是MySQL控制流函數(shù)之一,它接受兩個(gè)參數(shù) , 如果不是 NULL ,則返回第一個(gè)參數(shù),否則IFNULL函數(shù) 返回第二個(gè)參數(shù)
IFNULL(expression_1,expression_2);
如果expression_1不為NULL,則IFNULL函數(shù)返回expression_1; 否則返回expression_2的結(jié)果。
示例表如下所示:

#查找某位同學(xué)的聯(lián)系方式 (如果電話為空,使用郵箱) mysql> select name,ifnull(phone,email) as 聯(lián)系方式 from exam; +------+------------------+ | name | 聯(lián)系方式 | +------+------------------+ | 張華 | 13225631456 | | 李三 | 15698475235 | | 宋七 | 15236486952 | | 王五 | 15547522@163.com | | 趙四 | 13562698745 | | 李八 | 18625222@163.com | +------+------------------+ 6 rows in set (0.00 sec) #其中,王五和李八的電話為空,則使用其電子郵箱作為其聯(lián)系方式。
- 日期、時(shí)間函數(shù)
| now()函數(shù) | 返回當(dāng)前日期和時(shí)間。 |
|---|---|
| month()函數(shù) | 返回一個(gè)表示指定日期的月份的整數(shù)。 |
| year()函數(shù) | 返回日期值的年份部分。 |
| dayname()函數(shù) | 獲取指定日期的工作日的名稱(chēng)。 |
| round(數(shù)據(jù),n) 函數(shù) | 表示返回的數(shù)據(jù)保留n位小數(shù) |
mysql> select year('2018-01-01');
+--------------------+
| year('2018-01-01') |
+--------------------+
| 2018 |
+--------------------+
1 row in set
mysql> select dayname('2018-01-01') dayname;
+---------+
| dayname |
+---------+
| Monday |
+---------+
1 row in set1.2 GROUP BY子句
GROUP BY子句通過(guò)列或表達(dá)式的值將一組行分組為一個(gè)小分組的匯總行記錄。GROUP BY子句為每個(gè)分組返回一行。換句話說(shuō),它減少了結(jié)果集中的行數(shù),當(dāng)GROUP BY子句與聚合函數(shù)相結(jié)合時(shí), 可以返回每個(gè)分組的單個(gè)值。
#示例職工表
mysql> create table emp(
-> id int primary key auto_increment,
-> name varchar(20) not null,
-> role varchar(20) not null,
-> salary numeric(11,2)
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> insert into emp(name, role, salary) values
-> ('張三','科員', 2000.54),
-> ('宋七','副廳', 8996.99),
-> ('趙四','科員', 1800.11),
-> ('李八','科長(zhǎng)', 4540.5),
-> ('宋九','科員', 2356.33);
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from emp;
+----+------+------+---------+
| id | name | role | salary |
+----+------+------+---------+
| 1 | 張三 | 科員 | 2000.54 |
| 2 | 宋七 | 副廳 | 8996.99 |
| 3 | 趙四 | 科員 | 1800.11 |
| 4 | 李八 | 科長(zhǎng) | 4540.50 |
| 5 | 宋九 | 科員 | 2356.33 |
+----+------+------+---------+
5 rows in set (0.00 sec)對(duì)職工表進(jìn)行分組查詢(xún) , 查詢(xún)已知數(shù)據(jù)當(dāng)中每個(gè)職位的最低和最高工資
mysql> select role,max(salary),min(salary) from emp group by role; +------+-------------+-------------+ | role | max(salary) | min(salary) | +------+-------------+-------------+ | 副廳 | 8996.99 | 8996.99 | | 科員 | 2356.33 | 1800.11 | | 科長(zhǎng) | 4540.50 | 4540.50 | +------+-------------+-------------+ 3 rows in set (0.00 sec)
1.3 HAVING子句
GROUP BY子句進(jìn)行分組以后,需要對(duì)分組結(jié)果再進(jìn)行條件過(guò)濾時(shí),不能使用 WHERE 語(yǔ)句,而需要使用HAVING子句
再次對(duì)上述的職工表進(jìn)行操作,找出最高工資大于4000的職工職位角色和工資
mysql> select role,max(salary) from emp group by role having max(salary) > 4000; +------+-------------+ | role | max(salary) | +------+-------------+ | 副廳 | 8996.99 | | 科長(zhǎng) | 4540.50 | +------+-------------+ 2 rows in set (0.00 sec)
條件篩選可以使用where, order by, limit等來(lái)實(shí)現(xiàn),也可以不使用
HAVING子句和where語(yǔ)句的使用區(qū)別
- 分組之前指定條件, 也就是先篩選再分組, 使用
where關(guān)鍵字. - 分組之后指定條件, 也就是先分組再篩選, 使用
group by關(guān)鍵字
where和group by語(yǔ)法上要注意區(qū)分, where語(yǔ)句緊跟在表名后, 而having跟在group by后 .
示例:查詢(xún)工資小于5000的職工中,各職工角色的平均工資(保留兩位小數(shù))
mysql> select role,round(avg(salary)) from emp where salary < 5000 group by role; +------+--------------------+ | role | round(avg(salary)) | +------+--------------------+ | 科員 | 2052 | | 科長(zhǎng) | 4541 | +------+--------------------+ 2 rows in set (0.01 sec)
二 . 多表關(guān)系
- 概述
? 項(xiàng)目開(kāi)發(fā)當(dāng)中,在進(jìn)行數(shù)據(jù)庫(kù)的表結(jié)構(gòu)設(shè)計(jì)時(shí),會(huì)根據(jù)業(yè)務(wù)需求和業(yè)務(wù)模塊之間的關(guān)系,分析并設(shè)計(jì)表結(jié)構(gòu),由于業(yè)務(wù)之間相互關(guān)聯(lián),所以各個(gè)表結(jié)構(gòu)之間也存在著某種聯(lián)系 , 基本上分為三種: 一對(duì)多/多對(duì)多/一對(duì)一.
- 一對(duì)多(多對(duì)一)
案例 : 班級(jí)與學(xué)生的關(guān)系
關(guān)系 : 一個(gè)班級(jí)擁有多個(gè)學(xué)生 , 一個(gè)學(xué)生屬于一個(gè)班級(jí)
實(shí)現(xiàn) : 在多的 一方(學(xué)生) 建立外鍵, 指向另一方的主鍵

- 多對(duì)多
案例 : 學(xué)生與課程的關(guān)系
關(guān)系 :一名學(xué)生可以選修多門(mén)課程 , 一門(mén)課程也可以供多個(gè)學(xué)生來(lái)選擇 .
實(shí)現(xiàn) : 建立第三張中間表, 中間表中至少包含兩個(gè)外鍵,分別關(guān)聯(lián)兩表的主鍵

- 一對(duì)一
案例 : 用戶(hù)與用戶(hù)詳情之間的關(guān)系
關(guān)系 : 多用于單表拆分 , 將一張表的基礎(chǔ)字段放在一張表當(dāng)中 , 其他詳情字段放在另一張表當(dāng)中,以提升操作效率
實(shí)現(xiàn) : 在任意一方加入外鍵,關(guān)聯(lián)另一方的主鍵 , 并設(shè)置外鍵是唯一的

三、聯(lián)合查詢(xún)
實(shí)際開(kāi)發(fā)當(dāng)中往往要使用多個(gè)表的的數(shù)據(jù),所以需要多表聯(lián)合查詢(xún) , 多表聯(lián)合查詢(xún)時(shí)是對(duì)多張表的數(shù)據(jù)取笛卡爾積 , 然后對(duì)聯(lián)合表中篩選出需要的數(shù)據(jù)

對(duì)n條記錄的表A和m條記錄的表B進(jìn)行笛卡爾積,一共會(huì)產(chǎn)生n*m條記錄, 當(dāng)兩張表的數(shù)據(jù)量很大的時(shí)候, 這個(gè)操作就非常危險(xiǎn)了 , 需要慎重使用
mysql> select * from class; +----------+------------+ | id | name | +----------+------------+ | 1 | 計(jì)科1班 | | 2 | 計(jì)科2班 | +----------+------------+ 2 rows in set (0.00 sec) mysql> select * from student; +------+--------+----------+ | id | name | class_id | +------+--------+----------+ | 1 | 張三 | 1 | | 2 | 李四 | 1 | | 3 | 王五 | 2 | | 4 | 趙六 | 2 | +------+--------+----------+ #兩個(gè)表進(jìn)行笛卡爾集之后可以得到結(jié)果 mysql> select * from student, class; +------+--------+----------+----------+------------+ | id | name | class_id | id | name | +------+--------+----------+----------+------------+ | 1 | 張三 | 1 | 1 | 計(jì)科1班 | | 1 | 張三 | 1 | 2 | 計(jì)科2班 | | 2 | 李四 | 1 | 1 | 計(jì)科1班 | | 2 | 李四 | 1 | 2 | 計(jì)科2班 | | 3 | 王五 | 2 | 1 | 計(jì)科1班 | | 3 | 王五 | 2 | 2 | 計(jì)科2班 | | 4 | 趙六 | 2 | 1 | 計(jì)科1班 | | 4 | 趙六 | 2 | 2 | 計(jì)科2班 | +------+--------+----------+----------+------------+ 8 rows in set (0.00 sec)
上述兩表進(jìn)行笛卡爾集之后 , 得到了 4 * 2 即 8 條的結(jié)果 , 在這之中只有class_id相同的數(shù)據(jù)才是有效數(shù)據(jù) , 所以要添加限制條件 才能篩選出有效數(shù)據(jù)
3.1 內(nèi)連接
內(nèi)連接查詢(xún)的是兩張表交集的部分
- 隱式內(nèi)連接
select 字段列表 from 表1 ,表2 where ... = .. .;
- 顯式內(nèi)連接
select 字段列表 from 表1 inner join 表2 on 連接條件
以上述兩張學(xué)生表和課程表為例 , 查詢(xún)一名學(xué)生的姓名 , 以及該學(xué)生所在的班級(jí)名稱(chēng)
#隱式內(nèi)連接
mysql> select student.name, class.name from class,student
-> where student.class_id = class.id;
+------+---------+
| name | name |
+------+---------+
| 張三 | 計(jì)科1班 |
| 李四 | 計(jì)科1班 |
| 王五 | 計(jì)科2班 |
| 趙六 | 計(jì)科2班 |
+------+---------+
4 rows in set (0.01 sec)
# 也可以對(duì)表名起一個(gè)別名
mysql> select s.name, c.name from class c,student s
-> where s.class_id = c.id;
+------+---------+
| name | name |
+------+---------+
| 張三 | 計(jì)科1班 |
| 李四 | 計(jì)科1班 |
| 王五 | 計(jì)科2班 |
| 趙六 | 計(jì)科2班 |
+------+---------+
4 rows in set (0.00 sec)
#顯式內(nèi)連接
mysql> select student.name, class.name from student inner join class on student.class_id = class.id;
+------+---------+
| name | name |
+------+---------+
| 張三 | 計(jì)科1班 |
| 李四 | 計(jì)科1班 |
| 王五 | 計(jì)科2班 |
| 趙六 | 計(jì)科2班 |
+------+---------+
4 rows in set (0.03 sec)3.2 外連接
- 左外連接

相當(dāng)于查詢(xún)表1(左表)所有的數(shù)據(jù)包含表1和表2交集部分的數(shù)據(jù)
select 字段列表 from 表1 left join 表2 on 條件 ... ;
- 右外連接

相當(dāng)于查詢(xún)表2(右表)的所有數(shù)據(jù) , 包含表1 和表2 交集部分的數(shù)據(jù)
select 字段列表 from 表1 right join 表2 on 條件 ....;
示例:
#表結(jié)構(gòu)如下所示 mysql> select * from class; +----+---------+ | id | name | +----+---------+ | 1 | 計(jì)科1班 | | 2 | 計(jì)科2班 | | 3 | NULL | +----+---------+ 3 rows in set (0.00 sec) mysql> select * from student; +----+------+----------+ | id | name | class_id | +----+------+----------+ | 1 | 張三 | 1 | | 2 | 李四 | 1 | | 3 | 王五 | 2 | | 4 | 趙六 | 2 | | 5 | 宋六 | NULL | +----+------+----------+ 5 rows in set (0.01 sec) mysql> select * from student left join class on student.class_id = class.id; +----+------+----------+------+---------+ | id | name | class_id | id | name | +----+------+----------+------+---------+ | 1 | 張三 | 1 | 1 | 計(jì)科1班 | | 2 | 李四 | 1 | 1 | 計(jì)科1班 | | 3 | 王五 | 2 | 2 | 計(jì)科2班 | | 4 | 趙六 | 2 | 2 | 計(jì)科2班 | | 5 | 宋六 | NULL | NULL | NULL | +----+------+----------+------+---------+ 5 rows in set (0.00 sec) mysql> select * from class left join student on class.id = student.class_id; +----+---------+------+------+----------+ | id | name | id | name | class_id | +----+---------+------+------+----------+ | 1 | 計(jì)科1班 | 1 | 張三 | 1 | | 1 | 計(jì)科1班 | 2 | 李四 | 1 | | 2 | 計(jì)科2班 | 3 | 王五 | 2 | | 2 | 計(jì)科2班 | 4 | 趙六 | 2 | | 3 | NULL | NULL | NULL | NULL | +----+---------+------+------+----------+ 5 rows in set (0.00 sec) #使用左外連接或者右外連接的前提一般是 , 需求的列中部分元素為空值,直接使用內(nèi)連接無(wú)法顯示出來(lái),所以采用左外連接或者 右外連接
3.3 自連接
自連接指的是在同一張表內(nèi)連接自身進(jìn)行查詢(xún) ,自連接查詢(xún)可以是內(nèi)連接查詢(xún)也可以是外連接查詢(xún) . (自連接查詢(xún)中表必需起別名)
select 字段列表 from 表A 別名A join 表A 別名B on 條件
案例 : 員工表中包含以下字段 : 員工 id , 員工姓名 name,員工年齡 age , 員工領(lǐng)導(dǎo)managerid
# 查詢(xún)員工以及所屬領(lǐng)導(dǎo)的名稱(chēng) (內(nèi)) select a.name,b.name from emp a,emp b where a.managerid = b.id; (查詢(xún)的結(jié)果不包含領(lǐng)導(dǎo)為null的字段) # 查詢(xún)所有員工及其領(lǐng)導(dǎo)的名字 , 如果員工沒(méi)有領(lǐng)導(dǎo), 也需要查詢(xún)出來(lái) select a.name '員工',b.name '領(lǐng)導(dǎo)' from emp a left join emp b on a.managerid = b.id; #使用左外連接會(huì)將所有員工的姓名全部顯示出來(lái), 包括沒(méi)有領(lǐng)導(dǎo)的
3.4 合并查詢(xún)
在實(shí)際應(yīng)用中,為了合并多個(gè)select的執(zhí)行結(jié)果,可以使用集合操作符 union,union all。使用UNION和UNION ALL時(shí),前后查詢(xún)的結(jié)果集中,字段需要一致。
union all
該操作符用于取得兩個(gè)結(jié)果集的并集。當(dāng)使用該操作符時(shí),不會(huì)去掉結(jié)果集中的重復(fù)行(合并后的結(jié)果中包含重復(fù)行)
select * from course where id<3 union all select * from course where name= '數(shù)據(jù)結(jié)構(gòu)'; # 當(dāng)查詢(xún)字段不一致時(shí)會(huì)報(bào)錯(cuò)
union
該操作符用于取得兩個(gè)結(jié)果集的并集。當(dāng)使用該操作符時(shí),會(huì)自動(dòng)去掉結(jié)果集中的重復(fù)行
select * from course where id<3 union select * from course where name= '數(shù)據(jù)結(jié)構(gòu)';
同理 or
select * from course where id < 3 or name = '數(shù)據(jù)結(jié)構(gòu)';
union查詢(xún)時(shí),在索引列查詢(xún)速度快,or,in采用的是全表掃描機(jī)制更適用于非索引列查找。
3.4 子查詢(xún)
- 概念 : SQL語(yǔ)句中嵌套select語(yǔ)句 , 稱(chēng)為嵌套查詢(xún) , 又稱(chēng)子查詢(xún) .
select * from table1 where column1 = (select column1 fropm table2);
子查詢(xún)外部的語(yǔ)句可以是 : INSERT / UPDATE / SELECT 中的任何一個(gè)
- 標(biāo)量子查詢(xún)
子查詢(xún)返回的結(jié)果為單個(gè)值(數(shù)字,字符串,日期)等, 常用操作符: = <> > >= < <=
#查詢(xún)張三同學(xué)的同班同學(xué) select * from student where class_id =(select class_id from student where name = '張三');
- 列子查詢(xún)
子查詢(xún)返回的結(jié)果是 一列(可以是多行) ,這種子查詢(xún)稱(chēng)為列子查詢(xún) .
常用的操作符為 : IN , NOT IN , ANY ,ALL

# 查詢(xún)選修課程名稱(chēng)為語(yǔ)文或者英語(yǔ)的分?jǐn)?shù)信息 (in) select * from score where course_id in (select id from course where name='語(yǔ)文' or name='英文'); #查詢(xún)語(yǔ)文課程分?jǐn)?shù)大于其他任意一名學(xué)生的信息(any) select * from score where grade>any(select grade from score where course_id = (select class_id from student where name = '語(yǔ)文'));
- exists關(guān)鍵字
exists( )內(nèi)子查詢(xún)語(yǔ)句返回結(jié)果不為空,說(shuō)明where條件成立就會(huì)執(zhí)行主sql語(yǔ)句。如果為空就表示where條件不成立,sql語(yǔ)句就不會(huì)執(zhí)行。not exists 和 exists相反,子查詢(xún)語(yǔ)句結(jié)果為空,則表示where條件成立,執(zhí)行sql語(yǔ)句。否則不執(zhí)行。
- 在from子句中使用子查詢(xún):子查詢(xún)語(yǔ)句出現(xiàn)在from子句中。這里要用到數(shù)據(jù)查詢(xún)的技巧,把一個(gè)子查詢(xún)當(dāng)做一個(gè)臨時(shí)表使用
-- 獲取“計(jì)算機(jī)1班”的平均分,將其看作臨時(shí)表 select avg( sco.score ) score from score sco join student stu ON sco.student_id = stu.id join classes cls ON stu.classes_id = cls.id where cls.NAME = '計(jì)算機(jī)1班';
到此這篇關(guān)于MySQL表聚合與聯(lián)合查詢(xún)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)MySQL聚合與聯(lián)合查詢(xún)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
10個(gè)MySQL性能調(diào)優(yōu)的方法
本文介紹了10個(gè)MySQL性能調(diào)優(yōu)的方法,每個(gè)方法的講解都很細(xì)致,非常實(shí)用,,需要的朋友可以參考下2015-07-07
windows10系統(tǒng)安裝mysql-8.0.13(zip安裝) 的教程詳解
這篇文章主要介紹了windows10安裝mysql-8.0.13(zip安裝) 的教程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11
mysql 1130錯(cuò)誤,無(wú)法登錄遠(yuǎn)程服務(wù)的解決
這篇文章主要介紹了mysql 1130錯(cuò)誤,無(wú)法登錄遠(yuǎn)程服務(wù)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
Navicat 遠(yuǎn)程連接 MySQL實(shí)現(xiàn)步驟解析
這篇文章主要介紹了Navicat 遠(yuǎn)程連接 MySQL實(shí)現(xiàn)步驟解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
Windows下mysql community server 8.0.16安裝配置方法圖文教程
這篇文章主要為大家詳細(xì)介紹了Windows下mysql community server 8.0.16安裝配置方法圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06
ORM模型框架操作mysql數(shù)據(jù)庫(kù)的方法
ORM 全稱(chēng)是(Object Relational Mapping)表示對(duì)象關(guān)系映射; 通俗理解可以理解為編程語(yǔ)言的虛擬數(shù)據(jù)庫(kù);這篇文章主要介紹了ORM模型框架操作mysql數(shù)據(jù)庫(kù)的方法,需要的朋友可以參考下2021-07-07

