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)
作者:碼農有道
如果文章有錯別字,或者內容有錯誤,或其他的建議和意見,請您留言指正,非常感謝!!!