日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

mysql数据库入门教程(5):多表操作(连接查询,子查询,分页查询,联合查询)

發(fā)布時(shí)間:2024/9/30 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql数据库入门教程(5):多表操作(连接查询,子查询,分页查询,联合查询) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前文介紹了單表查詢: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ǔ)句

SELECT NAME,boyName FROM beauty ,boys;

得到結(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
*/

USE myemployees;#查詢員工名、工種號(hào)、工種名SELECT e.last_name,e.job_id,j.job_title FROM employees e,jobs j WHERE e.`job_id`=j.`job_id`;

兩個(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。

#案例:查詢有獎(jiǎng)金的員工名、部門名SELECT last_name,department_name,commission_pct FROM employees e,departments d WHERE e.`department_id`=d.`department_id` AND e.`commission_pct` IS NOT NULL;

可以加分組

#案例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í)就用到的自連接。

#案例:查詢 員工名和上級(jí)的名稱SELECT e.employee_id,e.last_name,m.employee_id,m.last_name FROM employees e,employees m WHERE e.`manager_id`=m.`employee_id`;

二.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ǔ)法中的等值連接效果是一樣的,都是查詢多表的交集

#案例1.查詢員工名、部門名SELECT last_name,department_name FROM departments dJOIN employees e ON e.`department_id` = d.`department_id`; #案例2.查詢名字中包含e的員工名和工種名(添加篩選) SELECT last_name,job_title FROM employees e INNER JOIN jobs j ON e.`job_id`= j.`job_id` WHERE e.`last_name` LIKE '%e%'; #3. 查詢部門個(gè)數(shù)>3的城市名和部門個(gè)數(shù),(添加分組+篩選)#①查詢每個(gè)城市的部門個(gè)數(shù) #②在①結(jié)果上篩選滿足條件的 SELECT city,COUNT(*) 部門個(gè)數(shù) FROM departments d INNER JOIN locations l ON d.`location_id`=l.`location_id` GROUP BY city HAVING COUNT(*)>3;

三表連接

#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)有的
*/

#引入:查詢男朋友 不在男神表的的女神名USE girls;SELECT * FROM beauty; SELECT * FROM boys; #左外連接 SELECT b.*,bo.* FROM beauty b LEFT OUTER JOIN boys bo ON b.`boyfriend_id` = bo.`id`

主表為beauty

如果將上述代碼改為右連接
主表為boys

USE myemployees;#案例1:查詢哪個(gè)部門沒(méi)有員工#左外SELECT d.*,e.employee_idFROM departments dLEFT OUTER JOIN employees eON d.`department_id` = e.`department_id`WHERE e.`employee_id` IS NULL; USE myemployees; #右外SELECT d.*,e.employee_idFROM employees eRIGHT OUTER JOIN departments dON d.`department_id` = e.`department_id`WHERE e.`employee_id` IS NULL;

主表為部門

5.sql99語(yǔ)法的全外連接

語(yǔ)法不支持
介紹下語(yǔ)法

#全外USE girls;SELECT b.*,bo.*FROM beauty bFULL OUTER JOIN boys boON b.`boyfriend_id` = bo.id;

6.sql99語(yǔ)法的交叉連接
交叉連接即笛卡爾乘積的實(shí)現(xiàn)

USE girls;#交叉連接SELECT b.*,bo.*FROM beauty bCROSS JOIN boys bo;

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è)值

USE myemployees; #1.標(biāo)量子查詢★#案例1:誰(shuí)的工資比 Abel 高?#①查詢Abel的工資 SELECT salary FROM employees WHERE last_name = 'Abel'#②查詢員工的信息,滿足 salary>①結(jié)果 SELECT * FROM employees WHERE salary>(SELECT salaryFROM employeesWHERE last_name = 'Abel'); #案例2:返回job_id與141號(hào)員工相同,salary比143號(hào)員工多的員工 姓名,job_id 和工資#①查詢141號(hào)員工的job_id SELECT job_id FROM employees WHERE employee_id = 141#②查詢143號(hào)員工的salary SELECT salary FROM employees WHERE employee_id = 143#③查詢員工的姓名,job_id 和工資,要求job_id=①并且salary>②SELECT last_name,job_id,salary FROM employees WHERE job_id = (SELECT job_idFROM employeesWHERE employee_id = 141 ) AND salary>(SELECT salaryFROM employeesWHERE employee_id = 143);

使用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)行查詢。

USE myemployees;#案例1:返回location_id是1400或1700的部門中的所有員工姓名#①查詢location_id是1400或1700的部門編號(hào) SELECT DISTINCT department_id FROM departments WHERE location_id IN(1400,1700)#②查詢員工姓名,要求部門號(hào)是①列表中的某一個(gè)SELECT last_name FROM employees WHERE department_id <>ALL(SELECT DISTINCT department_idFROM departmentsWHERE location_id IN(1400,1700));#《》all =in #案例2:返回其它工種中比job_id為‘IT_PROG’工種任一工資低的員工的員工號(hào)、姓名、job_id 以及salary#①查詢job_id為‘IT_PROG’部門任一工資SELECT DISTINCT salary FROM employees WHERE job_id = 'IT_PROG'#②查詢員工號(hào)、姓名、job_id 以及salary,salary<(①)的任意一個(gè) SELECT last_name,employee_id,job_id,salary FROM employees WHERE salary<ANY(SELECT DISTINCT salaryFROM employeesWHERE job_id = 'IT_PROG') AND job_id<>'IT_PROG';

3.where后面的行子查詢使用
子查詢是一行多列或者多行多列

#案例:查詢員工編號(hào)最小并且工資最高的員工信息
原始方法

#①查詢最小的員工編號(hào) SELECT MIN(employee_id) FROM employees#②查詢最高工資 SELECT MAX(salary) FROM employees#③查詢員工信息 SELECT * FROM employees WHERE employee_id=(SELECT MIN(employee_id)FROM employees)AND salary=(SELECT MAX(salary)FROM employees);

多行查詢

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)量子查詢
*/

USE myemployees;#案例:查詢每個(gè)部門的員工個(gè)數(shù)SELECT d.*,(SELECT COUNT(*)FROM employees eWHERE e.department_id = d.`department_id`) 個(gè)數(shù)FROM departments d;

這一部分是個(gè)數(shù)

SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.department_id

5.from后面的子查詢使用

/*
將子查詢結(jié)果充當(dāng)一張表,要求必須起別名
*/

算例
#案例:查詢每個(gè)部門的平均工資的工資等級(jí)

#①查詢每個(gè)部門的平均工資 SELECT AVG(salary),department_id FROM employees GROUP BY department_id;

得到的是每個(gè)部門的平均工資

#等級(jí)表 SELECT * FROM job_grades;

等級(jí)表

#②連接①的結(jié)果集和job_grades表,篩選條件平均工資 between lowest_sal and highest_sal

SELECT ag_dep.*,g.`grade_level` FROM (SELECT AVG(salary) ag,department_idFROM employeesGROUP BY department_id ) ag_dep INNER JOIN job_grades g ON ag_dep.ag 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

SELECT department_name FROM departments d WHERE d.`department_id` IN(SELECT department_idFROM employees)

使用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條淘寶。

#案例1:查詢前五條員工信息 SELECT * FROM employees LIMIT 0,5; SELECT * FROM employees LIMIT 5; #案例:有獎(jiǎng)金的員工信息,并且工資較高的前10名顯示出來(lái) SELECT * FROMemployees WHERE commission_pct IS NOT NULL ORDER BY salary DESC LIMIT 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)
*/

#引入的案例:查詢部門編號(hào)>90或郵箱包含a的員工信息 #原始方法 SELECT * FROM employees WHERE email LIKE '%a%' OR department_id>90;; #現(xiàn)在 SELECT * FROM employees WHERE email LIKE '%a%' UNION SELECT * FROM employees WHERE department_id>90;

總結(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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。