mysql数据库入门教程(5):多表操作(连接查询,子查询,分页查询,联合查询)
前文介紹了單表查詢:mysql數(shù)據(jù)庫(kù)入門教程(4):查詢講解大全
今天介紹下多表查詢
一.連接查詢
含義:又稱多表查詢,當(dāng)查詢的字段來(lái)自于多個(gè)表時(shí),就會(huì)用到連接查詢
先送上下面所講用到的sql腳本
https://download.csdn.net/download/KOBEYU652453/12699277
其中有數(shù)據(jù)庫(kù)myemployees,girls
1笛卡爾乘積現(xiàn)象
笛卡爾乘積現(xiàn)象:表1 有m行,表2有n行,結(jié)果=m*n行
發(fā)生原因:沒(méi)有有效的連接條件
如何避免:添加有效的連接條件
如圖所示,beauty 表里有我們的女神,女神id,以及她的男朋友id
boys表結(jié)構(gòu)
如果我們想要把女神以及和她的男朋友整合成一張表。
如果我們使用語(yǔ)句
得到結(jié)果,是一個(gè)48行的表格,每個(gè)女神有多個(gè)男朋友?果然女神的世界,我們不懂。
這個(gè)表匹配出來(lái)的結(jié)果不是我們想要的。
如何避免:添加有效的連接條件,如使第一張表的boyfriend_id 等于 第二張表的id
SELECT NAME,boyName FROM boys,beauty WHERE beauty.boyfriend_id= boys.id;2連接查詢分類
內(nèi)連接,外連接,交叉連接
3等值連接
#案例1:查詢女神名和對(duì)應(yīng)的男神名 SELECT NAME,boyName FROM boys,beauty WHERE beauty.boyfriend_id= boys.id; #案例2:查詢員工名和對(duì)應(yīng)的部門名 SELECT last_name,department_name FROM employees,departments WHERE employees.`department_id`=departments.`department_id`;#2、為表起別名
/*
①提高語(yǔ)句的簡(jiǎn)潔度
②區(qū)分多個(gè)重名的字段
注意:如果為表起了別名,則查詢的字段就不能使用原來(lái)的表名去限定
因?yàn)閳?zhí)行順序是先f(wàn)rom 再select
*/
兩個(gè)表的順序可以交換
#3、兩個(gè)表的順序是否可以調(diào)換 #查詢員工名、工種號(hào)、工種名 SELECT e.last_name,e.job_id,j.job_title FROM jobs j,employees e WHERE e.`job_id`=j.`job_id`;可以加篩選
因?yàn)榍懊嬗辛藈here,不能再加where,所以添加and。
可以加分組
#案例1:查詢每個(gè)城市的部門個(gè)數(shù) SELECT COUNT(*) 個(gè)數(shù),city FROM departments d,locations l WHERE d.`location_id`=l.`location_id` GROUP BY city;可以加排序
#案例:查詢每個(gè)工種的工種名和員工的個(gè)數(shù),并且按員工個(gè)數(shù)降序SELECT job_title,COUNT(*) FROM employees e,jobs j WHERE e.`job_id`=j.`job_id` GROUP BY job_title ORDER BY COUNT(*) DESC;可以實(shí)現(xiàn)三表連接
#案例:查詢員工名、部門名和所在的城市SELECT last_name,department_name,city FROM employees e,departments d,locations l WHERE e.`department_id`=d.`department_id` AND d.`location_id`=l.`location_id`;4自連接
自連接是一種特殊的等值查詢
把一張表 另命名兩次 就變成啦等值連接。
如表所示,原圖給出的員工ID 以及他的領(lǐng)導(dǎo)id,
我們想要直接把員工名與他的領(lǐng)導(dǎo)抽取出來(lái)做成一張表。
這時(shí)就用到的自連接。
二.sql99語(yǔ)法的連接查詢
前面講的是92語(yǔ)法。92語(yǔ)法把連接條件和篩選條件都放在啦where后面,可讀性較差。
99語(yǔ)法:連接條件放在on后面,篩選條件where,等后面
分類:
內(nèi)連接(★):inner
外連接
左外(★):left 【outer】
右外(★):right 【outer】
全外:full【outer】
交叉連接:cross
語(yǔ)法:
select 查詢列表
from 表1 別名 【連接類型】
join 表2 別名
on 連接條件
【where 篩選條件】
【group by 分組】
【having 篩選條件】
【order by 排序列表】
連接類型為前面分類提到的inner,leftouter…
如圖內(nèi)連接語(yǔ)法
#一)內(nèi)連接
/*
語(yǔ)法:
select 查詢列表
from 表1 別名
inner join 表2 別名
on 連接條件;
#sql92和 sql99pk
/*
功能:sql99支持的較多
可讀性:sql99實(shí)現(xiàn)連接條件和篩選條件的分離,可讀性較高
*/
1.sql99語(yǔ)法的等值連接
特點(diǎn):
①添加排序、分組、篩選
②inner可以省略
③ 篩選條件放在where后面,連接條件放在on后面,提高分離性,便于閱讀
④inner join連接和sql92語(yǔ)法中的等值連接效果是一樣的,都是查詢多表的交集
三表連接
#5.查詢員工名、部門名、工種名,并按部門名降序(添加三表連接)SELECT last_name,department_name,job_title FROM employees e INNER JOIN departments d ON e.`department_id`=d.`department_id` INNER JOIN jobs j ON e.`job_id` = j.`job_id`ORDER BY department_name DESC;2.sql99語(yǔ)法的非等值連接
語(yǔ)法 連接條件 :between and
#查詢員工的工資級(jí)別
創(chuàng)建級(jí)別表
USE myemployees;CREATE TABLE job_grades (grade_level VARCHAR(3),lowest_sal INT,highest_sal INT);INSERT INTO job_grades VALUES ('A', 1000, 2999);INSERT INTO job_grades VALUES ('B', 3000, 5999);INSERT INTO job_grades VALUES('C', 6000, 9999);INSERT INTO job_grades VALUES('D', 10000, 14999);INSERT INTO job_grades VALUES('E', 15000, 24999);INSERT INTO job_grades VALUES('F', 25000, 40000);查詢
#查詢員工的工資級(jí)別SELECT salary,grade_level FROM employees e JOIN job_grades g ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`; #查詢工資級(jí)別的個(gè)數(shù)>20的個(gè)數(shù),并且按工資級(jí)別降序SELECT COUNT(*),grade_level FROM employees eJOIN job_grades gON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`GROUP BY grade_levelHAVING COUNT(*)>20ORDER BY grade_level DESC;3.sql99語(yǔ)法的自連接
#查詢員工的名字、上級(jí)的名字SELECT e.last_name,m.last_nameFROM employees eJOIN employees mON e.`manager_id`= m.`employee_id`; #查詢姓名中包含字符k的員工的名字、上級(jí)的名字SELECT e.last_name,m.last_nameFROM employees eJOIN employees mON e.`manager_id`= m.`employee_id`WHERE e.`last_name` LIKE '%k%';4.sql99語(yǔ)法的左(右)外連接
/*
應(yīng)用場(chǎng)景:用于查詢一個(gè)表中有,另一個(gè)表沒(méi)有的記錄
特點(diǎn):
1、外連接的查詢結(jié)果為主表中的所有記錄
如果從表中有和它匹配的,則顯示匹配的值
如果從表中沒(méi)有和它匹配的,則顯示null
外連接查詢結(jié)果=內(nèi)連接結(jié)果+主表中有而從表沒(méi)有的記錄
2、左外連接,left join左邊的是主表
右外連接,right join右邊的是主表
3、左外和右外交換兩個(gè)表的順序,可以實(shí)現(xiàn)同樣的效果
4、全外連接=內(nèi)連接的結(jié)果+表1中有但表2沒(méi)有的+表2中有但表1沒(méi)有的
*/
主表為beauty
如果將上述代碼改為右連接
主表為boys
主表為部門
5.sql99語(yǔ)法的全外連接
語(yǔ)法不支持
介紹下語(yǔ)法
6.sql99語(yǔ)法的交叉連接
交叉連接即笛卡爾乘積的實(shí)現(xiàn)
7.sql99語(yǔ)法的總結(jié)
三.子查詢
#一、where或having后面
/*
1、標(biāo)量子查詢(單行子查詢)
2、列子查詢(多行子查詢)
3、行子查詢(多列多行)
特點(diǎn):
①子查詢放在小括號(hào)內(nèi)
②子查詢一般放在條件的右側(cè)
③標(biāo)量子查詢,一般搭配著單行操作符使用
< >= <= = <>
列子查詢,一般搭配著多行操作符使用
in、any/some、all
④子查詢的執(zhí)行優(yōu)先于主查詢執(zhí)行,主查詢的條件用到了子查詢的結(jié)果
*/
1.where后面的標(biāo)量子查詢使用
標(biāo)量子查詢 :子查詢的值是一個(gè)值
使用having
#案例4:查詢最低工資大于50號(hào)部門最低工資的部門id和其最低工資#①查詢50號(hào)部門的最低工資 SELECT MIN(salary) FROM employees WHERE department_id = 50#②查詢每個(gè)部門的最低工資SELECT MIN(salary),department_id FROM employees GROUP BY department_id#③ 在②基礎(chǔ)上篩選,滿足min(salary)>① SELECT MIN(salary),department_id FROM employees GROUP BY department_id HAVING MIN(salary)>(SELECT MIN(salary)FROM employeesWHERE department_id = 50 );2.where后面的列子查詢使用
列子查詢 即子查詢返回多行
需要結(jié)合多行操作符使用
多行操作符
in/not in 返回列表中的任意一個(gè)
any/some 和子查詢返回的某一個(gè)值進(jìn)行比較
all 和子查詢返回的所有值進(jìn)行查詢。
3.where后面的行子查詢使用
子查詢是一行多列或者多行多列
#案例:查詢員工編號(hào)最小并且工資最高的員工信息
原始方法
多行查詢
USE myemployees;#案例:查詢員工編號(hào)最小并且工資最高的員工信息SELECT MIN(employee_id),MAX(salary)FROM employees;SELECT * FROM employees WHERE (employee_id,salary)=(SELECT MIN(employee_id),MAX(salary)FROM employees );4.select后面的子查詢使用
/*
僅僅支持標(biāo)量子查詢
*/
這一部分是個(gè)數(shù)
SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.department_id
5.from后面的子查詢使用
/*
將子查詢結(jié)果充當(dāng)一張表,要求必須起別名
*/
算例
#案例:查詢每個(gè)部門的平均工資的工資等級(jí)
得到的是每個(gè)部門的平均工資
等級(jí)表
#②連接①的結(jié)果集和job_grades表,篩選條件平均工資 between lowest_sal and highest_sal
注釋:from 后面的是第一張表并取別名為ag_dep
INNER JOIN job_grades g 內(nèi)連接 等級(jí)表,并取別名g
SELECT ag_dep.*,g.grade_level:取出第一張表的全部,第二張等級(jí)表的等級(jí)。
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal; 連接條件
5.exists后面的子查詢使用
/*
語(yǔ)法:
exists(完整的查詢語(yǔ)句)
結(jié)果:
1或0
*/
一般來(lái)說(shuō),能用exists的都能用in查詢
#案例1:查詢有員工的部門名
使用In
使用exists
SELECT department_name FROM departments d WHERE EXISTS(SELECT *FROM employees eWHERE d.`department_id`=e.`department_id`);四.分頁(yè)查詢
如淘寶 搜索內(nèi)衣,內(nèi)衣商品有10萬(wàn)條,但淘寶不是一下把10萬(wàn)條請(qǐng)求出來(lái)再分頁(yè)顯示。
而是一次請(qǐng)求1頁(yè)的數(shù)據(jù),如10條淘寶。
五.聯(lián)合查詢
/*
union 聯(lián)合 合并:將多條查詢語(yǔ)句的結(jié)果合并成一個(gè)結(jié)果
語(yǔ)法:
查詢語(yǔ)句1
union
查詢語(yǔ)句2
union
…
應(yīng)用場(chǎng)景:
要查詢的結(jié)果來(lái)自于多個(gè)表,且多個(gè)表沒(méi)有直接的連接關(guān)系,但查詢的信息一致時(shí)
特點(diǎn):★
1、要求多條查詢語(yǔ)句的查詢列數(shù)是一致的!(select 查的列一致。原始表列可以不一致。
2、要求多條查詢語(yǔ)句的查詢的每一列的類型和順序最好一致
3、union關(guān)鍵字默認(rèn)去重,如果使用union all 可以包含重復(fù)項(xiàng)
*/
總結(jié):當(dāng)條件比較少時(shí)可以用or,當(dāng)條件多時(shí)推薦使用聯(lián)合查詢union
電氣專業(yè)的計(jì)算機(jī)萌新,寫博文不容易。如果你覺(jué)得本文對(duì)你有用,請(qǐng)點(diǎn)個(gè)贊支持下,謝謝。
總結(jié)
以上是生活随笔為你收集整理的mysql数据库入门教程(5):多表操作(连接查询,子查询,分页查询,联合查询)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 平安福如何全额退保
- 下一篇: mysql数据库入门教程(6):数据的增