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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

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

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

前文介紹了單表查詢:mysql數據庫入門教程(4):查詢講解大全
今天介紹下多表查詢

一.連接查詢

含義:又稱多表查詢,當查詢的字段來自于多個表時,就會用到連接查詢

先送上下面所講用到的sql腳本
https://download.csdn.net/download/KOBEYU652453/12699277

其中有數據庫myemployees,girls

1笛卡爾乘積現象

笛卡爾乘積現象:表1 有m行,表2有n行,結果=m*n行
發生原因:沒有有效的連接條件
如何避免:添加有效的連接條件

如圖所示,beauty 表里有我們的女神,女神id,以及她的男朋友id

boys表結構

如果我們想要把女神以及和她的男朋友整合成一張表。
如果我們使用語句

SELECT NAME,boyName FROM beauty ,boys;

得到結果,是一個48行的表格,每個女神有多個男朋友?果然女神的世界,我們不懂。
這個表匹配出來的結果不是我們想要的。

如何避免:添加有效的連接條件,如使第一張表的boyfriend_id 等于 第二張表的id

SELECT NAME,boyName FROM boys,beauty WHERE beauty.boyfriend_id= boys.id;

2連接查詢分類

內連接,外連接,交叉連接

3等值連接

#案例1:查詢女神名和對應的男神名 SELECT NAME,boyName FROM boys,beauty WHERE beauty.boyfriend_id= boys.id; #案例2:查詢員工名和對應的部門名 SELECT last_name,department_name FROM employees,departments WHERE employees.`department_id`=departments.`department_id`;

#2、為表起別名

/*
①提高語句的簡潔度
②區分多個重名的字段
注意:如果為表起了別名,則查詢的字段就不能使用原來的表名去限定
因為執行順序是先from 再select
*/

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

兩個表的順序可以交換

#3、兩個表的順序是否可以調換 #查詢員工名、工種號、工種名 SELECT e.last_name,e.job_id,j.job_title FROM jobs j,employees e WHERE e.`job_id`=j.`job_id`;

可以加篩選
因為前面有了where,不能再加where,所以添加and。

#案例:查詢有獎金的員工名、部門名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:查詢每個城市的部門個數 SELECT COUNT(*) 個數,city FROM departments d,locations l WHERE d.`location_id`=l.`location_id` GROUP BY city;

可以加排序

#案例:查詢每個工種的工種名和員工的個數,并且按員工個數降序SELECT job_title,COUNT(*) FROM employees e,jobs j WHERE e.`job_id`=j.`job_id` GROUP BY job_title ORDER BY COUNT(*) DESC;

可以實現三表連接

#案例:查詢員工名、部門名和所在的城市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 以及他的領導id,
我們想要直接把員工名與他的領導抽取出來做成一張表。
這時就用到的自連接。

#案例:查詢 員工名和上級的名稱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語法的連接查詢

前面講的是92語法。92語法把連接條件和篩選條件都放在啦where后面,可讀性較差。
99語法:連接條件放在on后面,篩選條件where,等后面

分類:
內連接(★):inner
外連接
左外(★):left 【outer】
右外(★):right 【outer】
全外:full【outer】
交叉連接:cross

語法:
select 查詢列表
from 表1 別名 【連接類型】
join 表2 別名
on 連接條件
【where 篩選條件】
【group by 分組】
【having 篩選條件】
【order by 排序列表】

連接類型為前面分類提到的inner,leftouter…
如圖內連接語法
#一)內連接
/*
語法:
select 查詢列表
from 表1 別名
inner join 表2 別名
on 連接條件;

#sql92和 sql99pk
/*
功能:sql99支持的較多
可讀性:sql99實現連接條件和篩選條件的分離,可讀性較高
*/

1.sql99語法的等值連接

特點:
①添加排序、分組、篩選
②inner可以省略
③ 篩選條件放在where后面,連接條件放在on后面,提高分離性,便于閱讀
④inner join連接和sql92語法中的等值連接效果是一樣的,都是查詢多表的交集

#案例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. 查詢部門個數>3的城市名和部門個數,(添加分組+篩選)#①查詢每個城市的部門個數 #②在①結果上篩選滿足條件的 SELECT city,COUNT(*) 部門個數 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語法的非等值連接

語法 連接條件 :between and

#查詢員工的工資級別

創建級別表

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);

查詢

#查詢員工的工資級別SELECT salary,grade_level FROM employees e JOIN job_grades g ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`; #查詢工資級別的個數>20的個數,并且按工資級別降序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語法的自連接

#查詢員工的名字、上級的名字SELECT e.last_name,m.last_nameFROM employees eJOIN employees mON e.`manager_id`= m.`employee_id`; #查詢姓名中包含字符k的員工的名字、上級的名字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語法的左(右)外連接

/*
應用場景:用于查詢一個表中有,另一個表沒有的記錄
特點:
1、外連接的查詢結果為主表中的所有記錄
如果從表中有和它匹配的,則顯示匹配的值
如果從表中沒有和它匹配的,則顯示null
外連接查詢結果=內連接結果+主表中有而從表沒有的記錄
2、左外連接,left join左邊的是主表
右外連接,right join右邊的是主表
3、左外和右外交換兩個表的順序,可以實現同樣的效果
4、全外連接=內連接的結果+表1中有但表2沒有的+表2中有但表1沒有的
*/

#引入:查詢男朋友 不在男神表的的女神名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:查詢哪個部門沒有員工#左外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語法的全外連接

語法不支持
介紹下語法

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

6.sql99語法的交叉連接
交叉連接即笛卡爾乘積的實現

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

7.sql99語法的總結

三.子查詢

#一、where或having后面
/*
1、標量子查詢(單行子查詢)
2、列子查詢(多行子查詢)
3、行子查詢(多列多行)
特點:
①子查詢放在小括號內
②子查詢一般放在條件的右側
③標量子查詢,一般搭配著單行操作符使用
< >= <= = <>
列子查詢,一般搭配著多行操作符使用
in、any/some、all
④子查詢的執行優先于主查詢執行,主查詢的條件用到了子查詢的結果
*/

1.where后面的標量子查詢使用
標量子查詢 :子查詢的值是一個值

USE myemployees; #1.標量子查詢★#案例1:誰的工資比 Abel 高?#①查詢Abel的工資 SELECT salary FROM employees WHERE last_name = 'Abel'#②查詢員工的信息,滿足 salary>①結果 SELECT * FROM employees WHERE salary>(SELECT salaryFROM employeesWHERE last_name = 'Abel'); #案例2:返回job_id與141號員工相同,salary比143號員工多的員工 姓名,job_id 和工資#①查詢141號員工的job_id SELECT job_id FROM employees WHERE employee_id = 141#②查詢143號員工的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號部門最低工資的部門id和其最低工資#①查詢50號部門的最低工資 SELECT MIN(salary) FROM employees WHERE department_id = 50#②查詢每個部門的最低工資SELECT MIN(salary),department_id FROM employees GROUP BY department_id#③ 在②基礎上篩選,滿足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后面的列子查詢使用

列子查詢 即子查詢返回多行
需要結合多行操作符使用

多行操作符
in/not in 返回列表中的任意一個
any/some 和子查詢返回的某一個值進行比較
all 和子查詢返回的所有值進行查詢。

USE myemployees;#案例1:返回location_id是1400或1700的部門中的所有員工姓名#①查詢location_id是1400或1700的部門編號 SELECT DISTINCT department_id FROM departments WHERE location_id IN(1400,1700)#②查詢員工姓名,要求部門號是①列表中的某一個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’工種任一工資低的員工的員工號、姓名、job_id 以及salary#①查詢job_id為‘IT_PROG’部門任一工資SELECT DISTINCT salary FROM employees WHERE job_id = 'IT_PROG'#②查詢員工號、姓名、job_id 以及salary,salary<(①)的任意一個 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后面的行子查詢使用
子查詢是一行多列或者多行多列

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

#①查詢最小的員工編號 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;#案例:查詢員工編號最小并且工資最高的員工信息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后面的子查詢使用

/*
僅僅支持標量子查詢
*/

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

這一部分是個數

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

5.from后面的子查詢使用

/*
將子查詢結果充當一張表,要求必須起別名
*/

算例
#案例:查詢每個部門的平均工資的工資等級

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

得到的是每個部門的平均工資

#等級表 SELECT * FROM job_grades;

等級表

#②連接①的結果集和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 內連接 等級表,并取別名g
SELECT ag_dep.*,g.grade_level:取出第一張表的全部,第二張等級表的等級。
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal; 連接條件

5.exists后面的子查詢使用

/*
語法:
exists(完整的查詢語句)
結果:
1或0
*/
一般來說,能用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`);

四.分頁查詢

如淘寶 搜索內衣,內衣商品有10萬條,但淘寶不是一下把10萬條請求出來再分頁顯示。
而是一次請求1頁的數據,如10條淘寶。

#案例1:查詢前五條員工信息 SELECT * FROM employees LIMIT 0,5; SELECT * FROM employees LIMIT 5; #案例:有獎金的員工信息,并且工資較高的前10名顯示出來 SELECT * FROMemployees WHERE commission_pct IS NOT NULL ORDER BY salary DESC LIMIT 10 ;

五.聯合查詢

/*
union 聯合 合并:將多條查詢語句的結果合并成一個結果
語法:
查詢語句1
union
查詢語句2
union

應用場景:
要查詢的結果來自于多個表,且多個表沒有直接的連接關系,但查詢的信息一致時
特點:★
1、要求多條查詢語句的查詢列數是一致的!(select 查的列一致。原始表列可以不一致。
2、要求多條查詢語句的查詢的每一列的類型和順序最好一致
3、union關鍵字默認去重,如果使用union all 可以包含重復項
*/

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

總結:當條件比較少時可以用or,當條件多時推薦使用聯合查詢union

電氣專業的計算機萌新,寫博文不容易。如果你覺得本文對你有用,請點個贊支持下,謝謝。

總結

以上是生活随笔為你收集整理的mysql数据库入门教程(5):多表操作(连接查询,子查询,分页查询,联合查询)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。