內鏈接和外鏈接

簡介

等值鏈接  非等值鏈接 特殊的自鏈接都屬於內鏈接sql

  • 內鏈接:符合鏈接的條件的數據被選中,不符合條件的數據被濾去
  • 外鏈接:外鏈接的結果集等於內鏈接的結果集加上匹配不上的記錄(一個也不能少)

如何實現外鏈接

(+)  把(+)字段對面的表的數據所有被匹配出來數據庫

select  distinactt m.id,m.first_name from s_emp e,s_emp m where  e.manager_id(+)=m.id;

(+)把領導表裏的普通員工用NULL匹配(這是鏈接條件)oracle

找普通員工也要從領導表中找,由於領導表中有絕對條件證實誰是領導,可是員工表裏沒有這個絕對條件。因此要把領導表中的數據所有匹配出來,因此(+)要加到員工表的字段上,這樣領導表裏的全部數據就都被匹配了(普通員工匹配的是NULL),要找普通員工時,只要找員工表裏匹配的manager_id是NULL的就能找到普通員工(這是過濾條件)spa

select distinct m.id, m.first_name from s_emp e, s_emp m where e.manager_id(+)=m.id and e.manager_id is null;

演示一:

select  *  from s_dept;
select  *  from s_region;

(1)內鏈接:要求顯示每一個部門的id  和部門對應的名字  以及對應的地區名3d

select d.id, d.name, r.name from s_dept d, s_region r where d.region_id=r.id;

 

  顯示了12條數據。blog

 

(2)業務擴展,成立新部門  id爲100,name爲test  region_id爲NULLio

 insert into  s_dept  values(100 ,‘test’,NULL);(表中的增長)

  

再用上面的方法查找就只找獲得原來的,新增長的找不到,由於region_id爲NULL。class

 

(3因此外鏈接使沒有地區編號的部門也要顯示出來,由於要把部門表裏的全部部門匹配顯示出來,那麼就要把(+)加在地區表上test

select d.id, d.name, r.name from s_dept d, s_region r where d.region_id=r.id(+)

。。。。。。擴展

 

演示二:

(1)內鏈接:統計每一個員工的id  salary,並顯示工資的工資級別(用到s_emp和salgrade表)

select e.id, e.salary, s.grade from s_emp e, salgrade s where e.salary between s.losal and s.hisal;

  。。。。。。

 

(2)有一天把老闆的工資改成12500,超出了salgrade的統計範圍。

update s_emp set salary=12500;

再用上面的方法找,老闆的就丟失了!

select e.id, e.salary, s.grade from s_emp e, salgrade s where e.salary between s.losal and s.hisal order by id;

  。。。。。。

  

  從結果能夠看出,沒有了「id=1」的老闆的項目。

  

(3因此要用外鏈接把超出統計範圍的員工信息也要顯示出來。由於要把員工信息表的全部信息匹配顯示出來,因此要在salgrade對應的的字段上加(+),這裏要加兩個。

select e.id, e.salary, s.grade from s_emp e, salgrade s where e.salary between s.losal(+) and s.hisal(+) order by id;

總結

每次寫外鏈接時,能夠先寫號內鏈接(寫好內鏈接要搞清楚表和表之間關係以及業務邏輯),再加上(+),就是用NULL匹配。由於外鏈接的結果集等於內鏈接的結果集加上匹配不上的記錄。

(+)字段對面的表的數據所有被匹配出來

(+)只針對oracle數據庫

可是全部數據庫的語法機制是差很少的,只是表現形式有變化 

  • 錶鏈接:
    • 內鏈接:
      • 等值
      • 非等值
      • 自鏈接
    • 外鏈接:
      • 等值
      • 非等值
      • 自鏈接

 額外補充

sql99中規定的內外鏈接

  • 內鏈接:
from  a表,b表   where 鏈接條件變爲99標準:
from  a表  join  b表  on  鏈接條件(過濾條件不能寫在一塊兒)
或者from  a表  inner join  b表  on  鏈接條件

演示:列出每一個部門的名字和對應的地區名

一般使用的:

select d.name, r.name from s_dept d, s_resgion r where d.region_id=r.id;

 

  99標準的:(通常不怎麼用)

select d.name, r.name from s_dept d, join s_region r on d.region_id=r.id;

  

  • 外鏈接
    • 左外鏈接:a表發起鏈接,a表的數據所有被匹配出來(經過NULL記錄來所有匹配)
from  a表  left outer  join  b表  on  鏈接條件;

   oracle使用的(+):

select d.name, r.name from s_dept d, s_region r where d.region_id=r.id(+);

  

 

99標準的:

select d.name, r.name from s_dept d left outer join s_region r on d.region_id=r.id;

       

    • 右外鏈接:b表發起鏈接,b表的數據所有被匹配出來
from  a表  right outer  join  b表  on  鏈接條件;
    • 全外鏈接:實際上只是一個邏輯概念,實際用途中沒什麼用。全外鏈接的結果集等於左外鏈接的結果集加上右外鏈接的結果集,而且排除重複部分(就是左右兩張表都所有匹配,a表b表書寫順序隨便)

     oracle沒法使用(+)實現全外鏈接

from  a表  full outer  join  b表  on  鏈接條件;

 

oracle的全外鏈接

引用兩個關鍵字union和union  all

  • union:能夠合併兩個結果集,而後排重
  • union  all:能夠合併兩個結果集(不排重)

好比:

select  id from  s_emp  unoin ; 輸出25條數據
select  id  from s_emp  unoin  all ; 輸出50條數據
相關文章
相關標籤/搜索