您的位置:首页 > 数据库

SQL中各种Join语句(left、right、full、inner)的区别

2017-02-24 16:09 597 查看
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

第一个查询就是最全面的陆运信息表。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: