多表聯合查詢
當需要獲取的數據分布在多張中,考慮使用聯合查詢
1、SQL92方式
2、SQL99方式
SQL92方式
1、笛卡爾積:將多個表的數據進行一一對應,所得到結果為多表的笛卡爾積。
結果的數量為所有表的數量的乘積。
select * from emp,dept
2、等值連接篩選
概念:先做表的笛卡爾積,然后篩選,篩選條件為等值篩選。
注意:條件為字段的值相同來進行篩選,字段的名字可以不同
查詢員工姓名,工作,薪資,部門名稱
select * from emp,dept where emp.deptno=dept.deptno
可以直接在select子句中使用字段直接獲取數據,但是效率比較低。建議字段前加上表名
注意:如果是公共字段,則必須聲明表名
select ename,job,sal,dname from emp,dept where emp.deptno=dept.deptno--等值連接篩選
select emp.ename,emp.job,emp.sal,dept.dname,emp.deptno from emp,dept where emp.deptno=dept.deptno
select e.ename,e.job,e.sal,d.dname from emp e,dept d where e.deptno=d.deptno and sal>2000--給表使用別名
3、不等值連接
查詢員工姓名,工作,工資,工資等級
select * from emp e,salgrade s where e.sal>=s.losal and e.sal<=s.hisal
4、自連接(自己與自己做笛卡爾積)
查詢員工姓名,工作,薪資,及上級領導姓名
select e1.ename,e1.job,e1.sal,e2.ename from emp e1,emp e2 where e1.mgr=e2.empno
5、外連接
左外連接:加在右邊,顯示左邊對應字段沒有值的數據
查詢員工姓名,工作,薪資,部門名稱及沒有部門的員工信息
select * from emp e,dept d where e.deptno=d.deptno(+)
右外連接:加在左邊,顯示右邊對應字段沒有值的數據
查詢員工姓名,工作,薪資,部門名稱及沒有員工信息的部門
select * from emp e,dept d where e.deptno(+)=d.deptno
SQL99方式
注意1:依然可以給表添加別名
注意2:如果使用on或者usering關鍵字對結果進行篩選,必須使用inner join作用表與表的連接,其中inner可以省略
注意3:外連接的 outer關鍵字可以省略不寫
注意4:依然可以繼續使用分組,having ,排序等
1、笛卡爾積:使用cross join 關鍵字
select 內容 from 表名 cross join
select * from emp cross join dept
2、篩選
查詢員工姓名,工作,薪資,部門名稱
1)自然連接:使用關鍵字 natural join
使用:select 內容 from 表名 natural join 表名
特點1:底層先笛卡爾積,然后按照所有的同名同值字段自動進行等值篩選。
問題1:如果只想按照部分字段結果篩選怎么辦?
問題2:如果想按照字段名不同,但是值相同進行等值篩選怎么辦?
select * from emp natural join dept
解決1:使用using關鍵字
作用1:指明使用指定的字段對聯合查詢的結果進行等值篩選
注意:指明的字段必須是兩表的同名同值字段
使用:select 內容 from 表名 inner join 表名 using(字段名,字段名,....)
select * from emp inner join dept using(deptno)
解決2:使用on關鍵字進行自定義連接條件篩選(等值篩選,不等值篩選)
注意:普通篩選條件使用where進行篩選,不要使用on進行。好處:SQL語句的閱讀性變強。
使用:select 內容 from 表名 inner join 表名 on 連接條件 where 普通篩選條件
select * from emp inner join dept on emp.deptno=dept.deptno where sal>2000
2)外連接:
左外連接:select 內容 from 表名 left outer join 表名 on 連接條件
查詢員工姓名,工作,薪資,部門名稱及沒有部門的員工信息
select * from emp e left outer join dept d on e.deptno=d.deptno
右外連接:select 內容 from 表名 right outer join 表名 on 連接條件
查詢員工姓名,工作,薪資,部門名稱及沒有員工的部門信息
select * from emp e right outer join dept d on e.deptno=d.deptno
全外連接:select 內容 from 表名 full outer join 表名 on 連接條件
select * from emp e full outer join dept d on e.deptno=d.deptno
3)自連接:
查詢員工及其上級領導姓名
select e1.*,e2.ename from emp e1 inner join emp e2 on e1.mgr=e2.empno
三表聯合查詢
SQL92實現
特點:易於書寫,難於閱讀
缺點:92的SQL語句結構不清晰
用法:
select 內容 (別名,連接符,去除重復,oracle函數,邏輯運算)
from 表名1,表名2,表名3...
where 條件(連接條件,普通篩選條件,where子句關鍵字)
group by 分組字段
having 多行函數篩選
order by 排序字段
查詢員工信息及部門名稱及所在城市名稱並且員工的工資大於2000或者有獎金
select e.*,d.dname,c.cname
from emp e,dept d,city c
where (e.deptno=d.deptno and d.loc=c.cid and sal>2000) or (e.deptno=d.deptno and d.loc=c.cid and comm is not null)
order by e.sal
SQL99實現
特點:難於書寫,易於閱讀
用法:
select 內容 from 表名1
inner join 表名2
on 連接條件
inner join 表名3
on 連接條件
where 普通篩選條件
group by 分組
having 多行函數篩選
order by 排序
查詢員工信息及部門名稱及所在城市名稱並且員工的工資大於2000或者有獎金
select * from emp e
inner join dept d
on e.deptno = d.deptno
inner join city c
on d.loc =c.cid
where e.sal>2000 or e.comm is not null
order by e.sal
子查詢
使用時機:當查詢的篩選條件不明確時,考慮使用子查詢。
1、單行子查詢
2、多行子查詢
單行子查詢
使用時機:篩選條件不明確需要執行一次查詢,並且查詢結果為一個字段並值只有一個
注意:where子句中允許出現查詢語句,該查詢語句稱為子查詢
使用:select 內容 from 表名 where 字段名 比較運算符 子查詢語句
查詢所有比雇員“CLARK”工資高的員工信息
select * from emp where sal>(select sal from emp where ename ='CLARK')
查詢工資高於平均工資的員工的名字和工資
select ename,sal from emp where sal>(select avg(sal) from emp )
查詢和soctt屬於同一部門且工資比他低的員工資料
select * from emp where deptno=(select deptno from emp where ename='SCOTT') and sal<(select sal from emp where ename='SCOTT')
查詢職務和scott相同,雇佣時間早的員工信息
select * from emp where job=(select job from emp where ename='SCOTT') and hiredate <(select hiredate from emp where ename='SCOTT')
多行子查詢
使用:子查詢的結果只有一個字段但是字段有n個值,考慮使用多行子查詢,其實就是使用關鍵字
關鍵字1:any 任意
select 內容 from 表名 where 字段名 比較運算符 any 子查詢語句
關鍵字2:all 所有
select 內容 from 表名 where 字段名 比較運算符 all 子查詢語句
關鍵字3:in 表示任意存在,相當於 = any
select 內容 from 表名 where 字段名 in 子查詢語句
select 內容 from 表名 where 字段名 not in 子查詢語句
查詢工資高於任意一個CLERK的所有員工信息
select * from emp where sal> any (select sal from emp where job='CLERK')
查詢工資高於所有SALESMAN的員工信息
select * from emp where sal> all (select sal from emp where job='SALESMAN')
查詢部門20中同部門10的雇員工作一樣的雇員信息
select job from emp where deptno=10
select * from emp where job in (select job from emp where deptno=10) and deptno=20
select * from emp where job = any (select job from emp where deptno=10) and deptno=20