SQL中各種Join語句(left、right、full、inner)的區別
阿新 • • 發佈:2019-02-10
iamlaosong文
實際工作中常常需要將多個表的查詢結果合成的一個查詢中,我一般採用join語句進行連線,用的最多的就是left join,這麼多join的差別是什麼呢?簡單的說就是最終結果以誰為主的問題。下面是個查詢語句例項:
select aa.city, aa.ssxs, aa.zj_code, aa.zj_mc, bb.clct, cc.dlv from sncn_zd_jg aa left join (select t.clct_bureau_org_code zj_code, count(*) clct from tb_evt_mail_clct t where t.clct_date = trunc(sysdate - 1) group by t.clct_bureau_org_code) bb on bb.zj_code = aa.zj_code left join (select t.dlv_bureau_org_code zj_code, count(*) dlv from tb_evt_dlv t where t.dlv_date = trunc(sysdate - 1) group by t.dlv_bureau_org_code) cc on cc.zj_code = aa.zj_code order by aa.city, aa.ssxs, aa.zj_code, aa.zj_mc
1、left join
左連線自然以連線條件的左邊為主,即前面一個查詢記錄(左邊)為主,如果前面的記錄中無內容,後面的查詢結果即使有內容也會被丟棄,如果前面的記錄中有內容,後面的查詢結果無內容,也會保留這一條記錄,只是後面的查詢結果為空而已,如下圖所示:
2、right join
理解了左連線,右連線理解也就簡單了,即以後面的結果為主,前面的結果如果沒有,則為空。
3、full join
全連線則是保留所有的查詢記錄,沒有的對應位置則為空。
4、inner join
和全連線相反,只保留所有查詢都有結果的記錄,其它都丟棄。
內連線另一種寫法是把查詢結果或者表都放在from關鍵字後面,而在條件語句中加上連線條件,這種寫法更常見,特別是多表關聯查詢的時候。 如:
select * from t1,t2 where t1.id=t2.id;
上面內連線的查詢語句也可以改成如下形式:
select aa.city, aa.ssxs, aa.zj_code, aa.zj_mc, bb.clct, cc.dlv from sncn_zd_jg aa, (select t.clct_bureau_org_code zj_code, count(*) clct from tb_evt_mail_clct t where t.clct_date = trunc(sysdate - 1) group by t.clct_bureau_org_code) bb, (select t.dlv_bureau_org_code zj_code, count(*) dlv from tb_evt_dlv t where t.dlv_date = trunc(sysdate - 1) group by t.dlv_bureau_org_code) cc where aa.zj_code = bb.zj_code and aa.zj_code = cc.zj_code order by aa.city, aa.ssxs, aa.zj_code, aa.zj_mc
同理,左連線也可改寫,只是需要在條件處後表字段後面加上“(+)”,如下所示:
select aa.city, aa.ssxs, aa.zj_code, aa.zj_mc, bb.clct, cc.dlv
from sncn_zd_jg aa,
(select t.clct_bureau_org_code zj_code, count(*) clct
from tb_evt_mail_clct t
where t.clct_date = trunc(sysdate - 1)
group by t.clct_bureau_org_code) bb,
(select t.dlv_bureau_org_code zj_code, count(*) dlv
from tb_evt_dlv t
where t.dlv_date = trunc(sysdate - 1)
group by t.dlv_bureau_org_code) cc
where aa.zj_code = bb.zj_code(+)
and aa.zj_code = cc.zj_code(+)
order by aa.city, aa.ssxs, aa.zj_code, aa.zj_mc
左連線的這種寫法似乎也是oracle獨有的(非標用法),其它資料庫系統並不支援。至於右連線嘛,也可以將“(+)”寫在左邊,或者將表或查詢結果調換位置,變成左連線。不過全連線似乎不能用這種形式。
實際工作中用的最多的是左連線,為了儘可能全面,第一個查詢應該選擇一個最全面的查詢,如下面這個例子:
select aa.cljds, aa.lybcf, bb.jkbcf, cc.ckbcf, dd.zybcf, ee.hkbcf
from (select t.pyjds cljds, sum(t.feiyong) lybcf
from emsapp_js_ly_bcf t
where t.jsrq between to_date('2017-1-1', 'yyyy-mm-dd') and
to_date('2017-1-1', 'yyyy-mm-dd')
group by t.pyjds) aa
left join (select t.cljds, sum(t.feiyong) jkbcf
from emsapp_js_jk_bcf t
where t.jsrq between to_date('2017-1-1', 'yyyy-mm-dd') and
to_date('2017-1-1', 'yyyy-mm-dd')
group by t.cljds) bb on bb.cljds = aa.cljds
left join (select t.cljds, sum(t.feiyong) ckbcf
from emsapp_js_ck_bcf t
where t.jsrq between to_date('2017-1-1', 'yyyy-mm-dd') and
to_date('2017-1-1', 'yyyy-mm-dd')
group by t.cljds) cc on cc.cljds = aa.cljds
left join (select t.cljds, sum(t.feiyong) zybcf
from emsapp_js_zy_bcf t
where t.jsrq between to_date('2017-1-1', 'yyyy-mm-dd') and
to_date('2017-1-1', 'yyyy-mm-dd')
group by t.cljds) dd on dd.cljds = aa.cljds
left join (select t.fcz cljds, sum(t.feiyong) hkbcf
from emsapp_js_hk_bcf t
where t.jsrq between to_date('2017-1-1', 'yyyy-mm-dd') and
to_date('2017-1-1', 'yyyy-mm-dd')
group by t.fcz) ee on ee.cljds = aa.cljds
order by aa.cljds
第一個查詢就是最全面的陸運資訊表。