Oracle join多表查詢


join(連接)是一個查詢,它將來自兩個或多個表、視圖的數據組合在一起。

我通過一些示例來向大家介紹join的常用方法。

一、生成測試數據

1、創建超女基本信息歷史表(T_GIRL_HIS)

create table T_GIRL_HIS
(
  id        char(4)         not null,   -- 編號
  name      varchar2(10)    not null,   -- 姓名
  yz        varchar2(10)        null,   -- 顏值
  sc        varchar2(10)        null,   -- 身材
  weight    number(4,1)     not null,   -- 體重
  height    number(3)       not null,   -- 身高
  birthday  date            not null,   -- 出生時間
  memo      varchar2(1000)      null,    -- 備注
  primary key(id)
);
insert into T_GIRL_HIS(id,name,yz,birthday,sc,weight,height,memo)
  values('0101','西施_H','漂亮',to_date('2000-01-01 01:12:35','yyyy-mm-dd hh24:mi:ss'),
         '火辣',48.5,170,'這是一個非常漂亮姑娘,老公是夫差,男朋友是范蠡。');
insert into T_GIRL_HIS(id,name,yz,birthday,sc,weight,height,memo)
  values('0102','貂禪_H','漂亮',to_date('1997-08-02 12:20:38','yyyy-mm-dd hh24:mi:ss'),
         '苗條',45.2,168,'王允真不是男人,干不過董卓就把美人往火坑里推,千古罪人啊。');
insert into T_GIRL_HIS(id,name,yz,birthday,sc,weight,height,memo)
  values('0103','妲已_H','漂亮',to_date('1998-03-03 10:50:33','yyyy-mm-dd hh24:mi:ss'),
         '火辣',53.6,172,'如果商真的因我而亡,您們男人做什么去了?');
insert into T_GIRL_HIS(id,name,yz,birthday,sc,weight,height,memo)
  values('0104','芙蓉姐姐_H','豬扒',to_date('1980-05-05 10:11:55','yyyy-mm-dd hh24:mi:ss'),
         '膘肥體壯',85.8,166,'如果不努力學習技術,將來就會娶個芙蓉姐姐,哼哼。');

2、創建超女基本信息表(T_GIRL)

create table T_GIRL
(
  id        char(4)         not null,   -- 編號
  name      varchar2(10)    not null,   -- 姓名
  yz        varchar2(10)        null,   -- 顏值
  sc        varchar2(10)        null,   -- 身材
  weight    number(4,1)     not null,   -- 體重
  height    number(3)       not null,   -- 身高
  birthday  date            not null,   -- 出生時間
  memo      varchar2(1000)      null,    -- 備注
  primary key(id)
);
insert into T_GIRL(id,name,yz,birthday,sc,weight,height,memo)
  values('0103','妲已','漂亮',to_date('1998-03-03 10:50:33','yyyy-mm-dd hh24:mi:ss'),
         '火辣',53.6,172,'如果商真的因我而亡,您們男人做什么去了?');
insert into T_GIRL(id,name,yz,birthday,sc,weight,height,memo)
  values('0104','芙蓉姐姐','豬扒',to_date('1980-05-05 10:11:55','yyyy-mm-dd hh24:mi:ss'),
         '膘肥體壯',85.8,166,'如果不努力學習技術,將來就會娶個芙蓉姐姐,哼哼。');
insert into T_GIRL(id,name,yz,birthday,sc,weight,height,memo)
  values('0105','神密貓女',null,to_date('1989-12-08 12:10:35','yyyy-mm-dd hh24:mi:ss'),
         null,48.5,171,'不知道是什么人,她臉上有一個%符號,很神密。');

3、測試數據說明

在這里插入圖片描述

在這里插入圖片描述

超女基本信息歷史表(T_GIRL_HIS)中有4條記錄,為了方便測試,每條記錄的姓名后面加了_H的標志,超女基本信息表(T_GIRL)中有3條記錄,姓名后沒有加_H。

T_GIRL_HIS和T_GIRL通過id列關聯起來,兩個表中有相交的記錄('0103'、'0104')。

二、表名限定

在SQL語句中,列是指表(視圖、結果集)的列,可以在列名前加表名限定,也可以用表的別名限定,例如:

1)不加表名限定

select id,name,scid,yzid,height,memo from T_GIRL;

2)用表名限定

select T_GIRL.id,T_GIRL.name,T_GIRL.scid,T_GIRL.yzid,T_GIRL.height,T_GIRL.memo from T_GIRL;

3)用表的別名限定

select aa.id,aa.name,aa.scid,aa.yzid,aa.height,aa.memo from T_GIRL aa;

以上三條SQL語句只操作了一個表,列名可以不用表名限定,但是,在join中,如果這多個表中有相同的列名,則必須在列名前面加表名限定,以避免歧義。

三、join示例

連接(join)分為五種,內連接(inner join),左連接(left join),右連接(right join)、全連接(full join)和笛卡兒乘積(cross join),常用的是內連接和左連接,其它的極少使用。

1、內連接(inner join)

在這里插入圖片描述

列出多個表或記錄連接字段的匹配記錄,即A表和B表的交集。

內連接有三種寫法,這三種寫法的效果相同。

1)標准的寫法。

select T_GIRL.id,T_GIRL.name,T_GIRL.sc,T_GIRL.yz,T_GIRL_HIS.id,T_GIRL_HIS.name
  from T_GIRL inner join T_GIRL_HIS on T_GIRL.id=T_GIRL_HIS.id;

2)省略inner,和第1)種寫法相比,只是省略了一個單詞而已,沒什么特別。

select T_GIRL.id,T_GIRL.name,T_GIRL.sc,T_GIRL.yz,T_GIRL_HIS.id,T_GIRL_HIS.name
  from T_GIRL join T_GIRL_HIS on T_GIRL.id=T_GIRL_HIS.id;

3)還有一種寫法。

select T_GIRL.id,T_GIRL.name,T_GIRL.sc,T_GIRL.yz,T_GIRL_HIS.id,T_GIRL_HIS.name
  from T_GIRL,T_GIRL_HIS where T_GIRL.id=T_GIRL_HIS.id;

在這里插入圖片描述

2、左連接(left join)

在這里插入圖片描述
列出左邊(A)表全部的,及右邊(B)表符合條件的,不符合條件的以空值代替,記錄總數為A表的記錄數。

左連接有兩種寫法,這兩種寫法的效果相同。

1)標准的寫法。

select T_GIRL.id,T_GIRL.name,T_GIRL.sc,T_GIRL.yz,T_GIRL_HIS.id,T_GIRL_HIS.name
  from T_GIRL left join T_GIRL_HIS on T_GIRL.id=T_GIRL_HIS.id;

2)采用(+),Oracle特有的寫法,其它數據庫不支持,注意(+)的位置,在右邊字段后面。

select T_GIRL.id,T_GIRL.name,T_GIRL.sc,T_GIRL.yz,T_GIRL_HIS.id,T_GIRL_HIS.name
  from T_GIRL,T_GIRL_HIS where T_GIRL.id=T_GIRL_HIS.id(+);

在這里插入圖片描述

3、右連接(right join)

在這里插入圖片描述

列出右邊(B)表全部的,及左邊(A)表符合條件的,不符合條件的以空值代替,記錄總數為B表的記錄數。

右連接有兩種寫法,這兩種寫法的效果相同。

1)標准的寫法。

select T_GIRL.id,T_GIRL.name,T_GIRL.sc,T_GIRL.yz,T_GIRL_HIS.id,T_GIRL_HIS.name
  from T_GIRL right join T_GIRL_HIS on T_GIRL.id=T_GIRL_HIS.id;

2)采用(+),Oracle特有的寫法,其它數據庫不支持,注意(+)的位置,在左邊字段后面。

select T_GIRL.id,T_GIRL.name,T_GIRL.sc,T_GIRL.yz,T_GIRL_HIS.id,T_GIRL_HIS.name
  from T_GIRL,T_GIRL_HIS where T_GIRL.id(+)=T_GIRL_HIS.id;

在這里插入圖片描述

右連接其實就是把左連接換個順序書寫,和左連接沒有任何本質的區別。

4、全連接(full join)

在這里插入圖片描述

列出右邊(B)表全部的,及左邊(A)表全部的,不符合條件的以空值代替,記錄總數為A表與B表的記錄數之和再減相交的記錄數。

select T_GIRL.id,T_GIRL.name,T_GIRL.sc,T_GIRL.yz,T_GIRL_HIS.id,T_GIRL_HIS.name
  from T_GIRL full join T_GIRL_HIS on T_GIRL.id=T_GIRL_HIS.id;

在這里插入圖片描述

5、笛卡兒乘積(cross join)

笛卡兒乘積連接,不加任何條件,記錄總數為兩個表相乘。

笛卡兒乘積連接有兩種寫法,這兩種寫法的效果相同。

select T_GIRL.id,T_GIRL.name,T_GIRL.sc,T_GIRL.yz,T_GIRL_HIS.id,T_GIRL_HIS.name
  from T_GIRL cross join T_GIRL_HIS;
select T_GIRL.id,T_GIRL.name,T_GIRL.sc,T_GIRL.yz,T_GIRL_HIS.id,T_GIRL_HIS.name
  from T_GIRL,T_GIRL_HIS;

在這里插入圖片描述

四、應用經驗

在實際開發中,內連接(inner join)和左連接(left join)經常使用,右連接(right join)和左連接本質上是同一回事,全連接(full join)和笛卡兒乘積(cross join)極少使用。

1、盡可能簡單化SQL語句

SQL語句非常強大,強大到很容易把人搞暈,例如多表操作,有經驗的程序員也很難應用自如。我極力反對過於復雜的SQL語句,復雜的SQL語句並不見得能體現程序員的水平,更像給自己和別人挖坑,合理的表結構設計不會讓查詢的SQL太復雜。

2、子查詢與join

1)join和子查詢都可以操作多個表,join和子查詢的區別是:join可以合並多個表的數據,而子查詢的數據只能來自一個表,子查詢的結果集用於嵌入SQL中。

2)有的查詢語句既可以使用子查詢,也可以使用join。如果使用子查詢,可以將一個復雜的查詢分解為一系列的步驟,條理清晰;但使用join有執行速度快的優點。

3)用join能實現的功能用子查詢都可以實現,但不是所有子查詢都能用join替換,子查詢比較靈活,方便,形式多樣,而join更適合查詢多表的數據。

4)如果表的數據量比較小,建議采用子查詢,如果數據量比較大,建議采用join,但是具體情況具體分析,多嘗試用PL/SQL Developer軟件提供的explain plan分析SQL語句的性能。

五、版權聲明

C語言技術網原創文章,轉載請說明文章的來源、作者和原文的鏈接。
來源:C語言技術網(www.freecplus.net)
作者:碼農有道

如果文章有錯別字,或者內容有錯誤,或其他的建議和意見,請您留言指正,非常感謝!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM