1. 程式人生 > >Mysql---複合查詢(多表連線、自連線、子查詢(any all) from子句查詢、union)

Mysql---複合查詢(多表連線、自連線、子查詢(any all) from子句查詢、union)

本篇部落格對錶的操作基於以下幾個表:

首先了解下簡單查詢即對一個表的查詢:
1.員工資訊表emp

mysql> select * from emp;

在這裡插入圖片描述
2.公司部門資訊表dept(部門號、部門名稱、位置)

mysql> select * from dept;

在這裡插入圖片描述
3.工資等級表salgrade(工資等級、當地工資、最高工資)
在這裡插入圖片描述

首先看幾個簡單查詢:
1.顯示每個部門的平均工資和最高工資

mysql> select deptno,avg(sal),max(sal) from emp group by deptno;

在這裡插入圖片描述
2.顯示平均工資低於2000的部門號和它的平均工資

mysql> select deptno,avg(sal) from emp group by deptno having avg(sal)<2000;

在這裡插入圖片描述
3.顯示每種崗位的僱員總數,平均工資

mysql> select job,count(*),avg(sal) from emp group by job;

在這裡插入圖片描述

接下來了解複合查詢:
多表連線
1.顯示僱員名、僱員工資以及所在部門的名字
因為要查詢的資料來自兩個表(emp和dept),這時就要把2個表利用相同屬性連線一起,可以發現2個表的相同屬性是deptno。

mysql> select ename,
sal,dname from emp,dept where emp.deptno=dept.deptno;

在這裡插入圖片描述
2.顯示部門號為10的部門名,員工名和工資

mysql> select dname,ename,sal from emp,dept where dept.deptno=10 and dept.deptno=emp.deptno;

在這裡插入圖片描述
3.顯示各個員工的姓名,工資,及工資級別
emp表和salgrade 2張表根據工資連線一起,找出員工工資符合salgrade 表的區間,即是工資等級。

mysql> select ename,sal,grade from emp,
salgrade where sal between losal and hisal;

在這裡插入圖片描述

自連線
自連線指同一張表連線查詢。

1.顯示員工FORD的上級領導的編號和姓名(mgr是員工領導的編號–empno)
方法1:使用子查詢
找出FORD領導的編號,根據這個編號查詢:

mysql> select empno,ename from emp where empno=(select mgr from emp where ename='FORD');

方法2:自查詢:leader表和worker表。leader表的員工編號等於worker表的FORD的領導編號。

mysql> select leader.empno,leader.ename from emp as leader,emp as worker where worker.ename='FORD' and leader.empno=worker.mgr;

在這裡插入圖片描述
子查詢
子查詢是指嵌入在其他sql語句中的select語句,也叫巢狀查詢。
單行子查詢:
例:顯示SMITH同一部門的員工

mysql> select * from emp where deptno=(select deptno from emp where ename='SMITH');

在這裡插入圖片描述

多行子查詢:
1.使用in關鍵字
查詢和10號部門的工作相同的僱員的名字,崗位,工資,部門號,但是不包含10自己的

mysql> select ename,job,sal,deptno from emp where job in(select job  from emp where deptno=10) and deptno<>10;

在這裡插入圖片描述
2.使用all關鍵字
顯示工資比部門30的所有員工的工資高的員工的姓名、工資和部門號
方法1:使用all關鍵字

mysql> select ename,sal,deptno from emp where sal>all(select sal from emp where deptno=30);

在這裡插入圖片描述
方法2:max函式

mysql> select ename, sal, deptno from emp where sal > (select max(sal) from emp where deptno=30);

在這裡插入圖片描述
3.使用any關鍵字;
顯示工資比部門30的任意員工的工資高的員工的姓名、工資和部門號
方法1:使用any

mysql> select ename,sal,deptno from emp where sal > any(select sal from emp where deptno=30);

方法2:min函式

mysql> select ename,sal,deptno from emp where sal > (select min(sal) from emp where deptno=30);

在這裡插入圖片描述
多列子查詢:
單行子查詢是指子查詢只返回單列,單行資料;多行子查詢是指返回單列多行資料,都是針對單列而言的,而多列
子查詢則是指查詢返回多個列資料的子查詢語句

例:查詢和SMITH的部門和崗位完全相同的所有僱員,不含SMITH本人

mysql> select ename,deptno,job from emp where (deptno,job)=(select deptno ,job from emp where ename='SMITH') and ename<>'SMITH';

在這裡插入圖片描述
在from子句中使用子查詢
把子查詢當做臨時表使用。
1.顯示高於自己部門平均工資的員工的姓名、部門、工資、平均工資

先把每個部門的平均工資生成一個臨時表tmp,再從emp和tmp表中查詢:

mysql> select ename,emp.deptno,sal,savg from emp,(select deptno ,avg(sal) as savg from emp group by deptno) as tmp
    -> where (emp.deptno=tmp.deptno) and (emp.sal> tmp.savg);

在這裡插入圖片描述

2.查詢每個部門工資最高的人的姓名、工資、部門、最高工資

先將每個部門的最高工資生成一個臨時表tmp,再從emp和tmp中匹配同一部門的最高工資。

mysql> select emp.ename,sal,emp.deptno,smax from emp,(select max(sal) as smax ,deptno from emp group by deptno) tmp
    -> where emp.deptno=tmp.deptno and sal=smax;

在這裡插入圖片描述

3.顯示每個部門的資訊(部門名,編號,地址)和人員數量
方法1:先找到每個部門的人員數量生成臨時表tmp,dept表和tmp連線:

mysql> select dname,dept.deptno,loc,empnum from dept,(select deptno,count(*) as empnum from emp group by deptno ) tmp
    -> where tmp.deptno=dept.deptno;

在這裡插入圖片描述
方法2:

mysql> select dept.deptno,dept.dname,dept.loc,count(*) from dept,emp where dept.deptno=emp.deptno group by dept.deptno;

在這裡插入圖片描述
可以在where子句中用連線:
例:獲取所有非manager的員工emp_no

CREATE TABLE `dept_manager` (
`dept_no` char(4) NOT NULL,
`emp_no` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));

方法1:

select emp_no from employees where
emp_no not in(select emp_no from dept_manager);

方法2:連線通常可以在select語句的from子句或where子句中建立。
left join(左連線)是以A表的記錄為基礎的,A可以看成左表,B可以看成右表,
left join是以左表為準的。
換句話說,左表(A)的記錄將會全部表示出來,
而右表(B)只會顯示符合搜尋條件的記錄。
B表記錄不足的地方均為NULL。
如:select * from A left join B on A.ID = B.ID

select emp_no from (select * from dept_manager,employees where 
                   dept_manager.emp_no=employees.emp_no) tmp
where tmp.dept_no IS NULL;

合併查詢:
將多個select執行結果進行合併,可以用union和union all。
union:取得兩個結果集的並集。當使用該操作符時,會自動去掉結果集中的重複行。
例:將工資大於2500或職位是MANAGER的人找出來
方法1:(or)

mysql> select ename,sal,job from emp where sal>2500 or job='manager';

在這裡插入圖片描述
方法2:union:

mysql> select ename,sal,job from emp where sal>2500 union
    -> select ename,sal,job from emp where job='manager';

union all
該操作符用於取得兩個結果集的並集。當使用該操作符時,不會去掉結果集中的重複行。

mysql> select ename,sal,job from emp where sal>2500 union all
    -> select ename,sal,job from emp where job='manager';

在這裡插入圖片描述