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表結構
如果我們想要把女神以及和她的男朋友整合成一張表。
如果我們使用語句
得到結果,是一個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
*/
兩個表的順序可以交換
#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。
可以加分組
#案例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,
我們想要直接把員工名與他的領導抽取出來做成一張表。
這時就用到的自連接。
二.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語法中的等值連接效果是一樣的,都是查詢多表的交集
三表連接
#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沒有的
*/
主表為beauty
如果將上述代碼改為右連接
主表為boys
主表為部門
5.sql99語法的全外連接
語法不支持
介紹下語法
6.sql99語法的交叉連接
交叉連接即笛卡爾乘積的實現
7.sql99語法的總結
三.子查詢
#一、where或having后面
/*
1、標量子查詢(單行子查詢)
2、列子查詢(多行子查詢)
3、行子查詢(多列多行)
特點:
①子查詢放在小括號內
②子查詢一般放在條件的右側
③標量子查詢,一般搭配著單行操作符使用
< >= <= = <>
列子查詢,一般搭配著多行操作符使用
in、any/some、all
④子查詢的執行優先于主查詢執行,主查詢的條件用到了子查詢的結果
*/
1.where后面的標量子查詢使用
標量子查詢 :子查詢的值是一個值
使用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 和子查詢返回的所有值進行查詢。
3.where后面的行子查詢使用
子查詢是一行多列或者多行多列
#案例:查詢員工編號最小并且工資最高的員工信息
原始方法
多行查詢
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后面的子查詢使用
/*
僅僅支持標量子查詢
*/
這一部分是個數
SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.department_id
5.from后面的子查詢使用
/*
將子查詢結果充當一張表,要求必須起別名
*/
算例
#案例:查詢每個部門的平均工資的工資等級
得到的是每個部門的平均工資
等級表
#②連接①的結果集和job_grades表,篩選條件平均工資 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
使用exists
SELECT department_name FROM departments d WHERE EXISTS(SELECT *FROM employees eWHERE d.`department_id`=e.`department_id`);四.分頁查詢
如淘寶 搜索內衣,內衣商品有10萬條,但淘寶不是一下把10萬條請求出來再分頁顯示。
而是一次請求1頁的數據,如10條淘寶。
五.聯合查詢
/*
union 聯合 合并:將多條查詢語句的結果合并成一個結果
語法:
查詢語句1
union
查詢語句2
union
…
應用場景:
要查詢的結果來自于多個表,且多個表沒有直接的連接關系,但查詢的信息一致時
特點:★
1、要求多條查詢語句的查詢列數是一致的!(select 查的列一致。原始表列可以不一致。
2、要求多條查詢語句的查詢的每一列的類型和順序最好一致
3、union關鍵字默認去重,如果使用union all 可以包含重復項
*/
總結:當條件比較少時可以用or,當條件多時推薦使用聯合查詢union
電氣專業的計算機萌新,寫博文不容易。如果你覺得本文對你有用,請點個贊支持下,謝謝。
總結
以上是生活随笔為你收集整理的mysql数据库入门教程(5):多表操作(连接查询,子查询,分页查询,联合查询)的全部內容,希望文章能夠幫你解決所遇到的問題。