多表查詢數據庫
1.什麼是多表查詢?
一次select語句須要查詢的內容來自於不止一張表。
同時從多張表中查詢數據。spa
單表查詢:
select id,last_name,salary
from s_emp
where salary > 1400 and dept_id in(41,42)
order by salary desc,id asc;
單表查詢能查到的數據是有限的。數學
查詢全部員工的id、last_name?
select id,last_name
from s_emp;it
查詢全部部門的id、name?
select id,name
from s_dept;ast
查詢全部員工id、last_name以及所在部門的
id和name?
select id,last_name,id,name
from s_emp,s_dept;select
語法:
select ...
from 表1,表2,表3.....
where ...
order by ....;語法
出現字段名衝突時,要使用 表名.列名 的形式,
聲明可能出現衝突的字段來自於哪張表。
select s_emp.id,last_name,s_dept.id,name
from s_emp,s_dept;數據
還能夠給表名起一個別名。
起到的別名能夠在整個select語句中代替表名使用。
語法:
select 別名1.字段,別名2.字段......
from 表1 別名1,表2 別名2;關係型數據庫
查詢全部員工的id、last_name以及
所在部門的id、name?
select s1.id,s1.last_name,s2.id,s2.name
from s_emp s1,s_dept s2;查詢
2.消除笛卡爾積
笛卡爾積是數學運算中集合進行乘法運算所產生的結果集。
A = { 1 , 2 , 3 }
B = { a , b }
計算:A x B = {(1,a),(1,b),(2,a),(2,b)
(3,a),(3,b)}
一共有2x3=6個結果。
數據庫進行多表查詢,就會產生笛卡爾積。
表1:學生姓名錶
學號 姓名
1 張三
2 李四
3 王五
-------------------
表2:學生成績表
學號 分數
1 80
2 90
3 70
要求:查詢全部學生的id、姓名以及成績?
1 張三 1 80
1 張三 2 90
1 張三 3 70
2 李四 1 80
2 李四 2 90
2 李四 3 70
3 王五 1 80
3 王五 2 90
3 王五 3 70
思路:
使用where關鍵字增長、指定查詢條件,
從笛卡爾積中把不須要的數據篩除出去。
1)等值鏈接
將兩張表中產生關聯的字段使用等號進行鏈接。
查詢全部員工的id、last_name以及
所在部門的id、name?
字段:s_emp.dept_id = s_dept.id
select s1.id,s1.last_name,s2.id,s2.name
from s_emp s1,s_dept s2
where s1.dept_id = s2.id;
2)不等值鏈接
大於
大於等於
小於
小於等於
邏輯比較符:between in
查詢全部員工id、last_name以及
工資收入等級?
select e.id,e.last_name,g.name
from s_emp e,s_gender g
where e.salary between g.minSal and g.maxSal;
或者:where e.salary >=g.minSal
and e.salary <= g.maxSal;
表1:員工表
id salary
1 900
2 1300
3 2100
表2:工資等級表
最小值 最大值 等級名稱
0 1000 藍領
1000 1500 白領
1500 2500 金領
結果:
員工ID 員工工資 最小值 最大值 等級名稱
1 900 0 1000 藍領
1 900 1000 1500 白領
1 900 1500 2500 金領
2 1300 0 1000 藍領
2 1300 1000 1500 白領
2 1300 1500 2500 金領
3 2100 0 1000 藍領
3 2100 1000 1500 白領
3 2100 1500 2500 金領
3)外鏈接
a)左外鏈接
查詢全部員工的id、last_name以及
所在部門的id、name?
select s1.id,s1.last_name,s2.id,s2.name
from s_emp s1,s_dept s2
where s1.dept_id = s2.id;
SQL:insert into s_emp(id,last_name)
values(999,'_briup');
查詢全部員工的id、last_name以及
所在部門的id、name?要求把沒有部門的員工
也顯示出來?
思路:讓員工表 左外鏈接 到部門表。
左外鏈接:
A左外鏈接到B,就能夠查出來沒有B的A。
語法:
1)標準SQL
一套規範、標準
拿到任何一款關係型數據庫中執行。
select...
from 表1 left [outer] join 表2
on 鏈接條件;
select e.id,e.last_name,d.id,d.name
from s_emp e left join s_dept d
on e.dept_id = d.id;
兩張表順序不能顛倒。
2)Oracle特點語法
符號:(+)
原則:把(+)放在數據較少的一方。
語法和多表查詢的語法一致。
select e.id,e.last_name,d.id,d.name
from s_emp e,s_dept d
where e.dept_id = d.id(+);
練習:
查詢全部員工信息和部門信息,
要求把沒有員工的部門也顯示出來?
select e.id,e.last_name,d.id,d.name
from s_emp e,s_dept d
where e.dept_id(+)= d.id;
b)右外鏈接
右外鏈接和左外鏈接就是相反的。
A表左外鏈接到B表,至關於B表右外鏈接到A表。
語法:
select...
from 表1 right [outer] join 表2
on 鏈接條件;
左外鏈接:
select e.id,e.last_name,d.id,d.name
from s_emp e left join s_dept d
on e.dept_id = d.id;
右外鏈接:
select e.id,e.last_name,d.id,d.name
from s_dept d right join s_emp e
on e.dept_id = d.id;
以上兩種寫法是等價的。
練習:
先向數據庫中插入一條數據:
insert into s_dept(id,name)
values(1000,'Teaching');
commit;
查詢全部員工的id、last_name以及對應部門的
id、name?要求把沒有員工的部門也查詢出來?
使用左外鏈接和右外鏈接兩種方式。
c)全鏈接
等同於同時包含左外鏈接和右外鏈接。
至關於A表同時左右外鏈接到B表,
或A、B兩表互爲左/右外鏈接。
語法:
select ...
from 表1 full join 表2
on 鏈接條件;
查詢全部員工的信息和部門信息?
要求把全部沒有員工的部門
以及沒有部門的員工所有都顯示出來?
select e.id,e.last_name,d.id,d.name
from s_emp e full join s_dept d
on e.dept_id = d.id;
全鏈接沒有Oracle特點語法,
若是要使用全鏈接,必須寫標準SQL。
4)自鏈接
一張表本身和本身產生關聯。
一張表,查詢的時候當成多張表使用。
查詢全部員工的id、last_name以及
對應經理的id、last_name?
要求把沒有經理的員工也顯示出來?
關係:員工的manager_id = 經理的id;
select s1.id,s1.last_name,s2.id,s2.last_name
from s_emp s1,s_emp s2
where s1.manager_id = s2.id(+);
編號 姓名 經理編號
1 張三 7
2 李四 9
....
7 王五 10
9 趙六 10
5)集合鏈接
查詢前20條數據 - 查詢前10條數據
3.Oracle數據庫中的僞列
僞列不用來存儲數據,因此不是一個真正意義的字段。
也不存在於任何一張表中。
僞列出如今每一次select查詢語句的結果中。
1)rowid
標識當前數據的物理存儲位置。
select id,last_name,rowid
from s_emp;
2)rownum
標識當前查詢結果中數據的標號。
注意:rownum必須從1開始。
先有查詢結果,再有rownum字段。
select id,last_name,rownum
from s_emp;
查詢員工表中前十條數據?
select id,last_name
from s_emp
where rownum <= 10;
查詢員工表中第11-20條數據?
select id,last_name
from s_emp
where rownum>=11 and rownum <=20;
select id,last_name,salary from (select id,last_name,rownum as rn from s_emp) e where rn >=11 and rn <=20;