加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

实例演示 多表关联之left join

(2014-06-20 16:19:53)
标签:

sql

left

join

详解

实例

分类: IT技术

创建4张表a,b,c,d

4张表结构相同,a(id integer, n varchar2(10))

其中表的数据记录如下:

http://s9/mw690/001sIItLgy6JP7Csqow38&690多表关联之left join" TITLE="实例演示 多表关联之left join" />

不同的查询,关联方式,查询的结果是不同的

第一种

select a.id, a.n a, b.n b, c.n c
  from tmp_1 a
  left join tmp_2 b
    on a.id = b.id
  left join tmp_3 c
    on a.id = c.id
 order by 1;

结果:

http://s12/mw690/001sIItLgy6JP7MyQYzcb&690多表关联之left join" TITLE="实例演示 多表关联之left join" />
第二种

select a.id, a.n a, b.n b, c.n c
  from tmp_1 a
  left join tmp_2 b
    on a.id = b.id
  left join tmp_3 c
    on b.id = c.id
 order by 1;
结果:

http://s15/mw690/001sIItLgy6JP7Wecwu9e&690多表关联之left join" TITLE="实例演示 多表关联之left join" />
可见,对应C表中的id=5的数据没有查询出来,因为b中没有。

第三种:带等值连接的

select a.id, a.n a, b.n b, c.n c, d.n d
  from tmp_1 a
  left join tmp_2 b
    on a.id = b.id
  left join tmp_3 c
    on a.id = c.id
 inner join tmp_4 d
    on a.id = d.id
 order by 1;

结果:

http://s2/mw690/001sIItLgy6JP86REGdd1&690多表关联之left join" TITLE="实例演示 多表关联之left join" />

第四种:

select a.id, a.n a, b.n b, c.n c, d.n d
  from tmp_1 a
  left join tmp_2 b
    on a.id = b.id
  left join tmp_3 c
    on a.id = c.id
 inner join tmp_4 d
    on c.id = d.id
 order by 1;
结果:

http://s3/mw690/001sIItLgy6JP8fg1Gif2&690多表关联之left join" TITLE="实例演示 多表关联之left join" />
相比前一种,少了id=2的记录,因为C中没有id=2的记录

 

总结:

1、结果与关联的表及字段有关,与关联关系出现在sql中的顺序无关。

2、对于非等值连接,针对右表的限制条件应该紧随left join给出。

 例如,上面所有的SQL中,如果表B还有其它限制条件,最好采取如下方式更易于理解:

 left join tmp_2 b
on a.id = b.id and b.xx=xxx...

测试发现,上面的例子跟下面的这个sql相同:

 left join tmp_2 b
on a.id = b.id

where b.xx=xxx...

 

实际工作中遇到的一个例子

select r.unit_id bd_unit_id,
       func_cm_getnamebylang('md_bd_organization', 'org_name',
                             nvl(r.unit_id, -1), 'en_US') bd_unit_name,
       m.sbu_key_code rp_account_code,
       m.item_code,
       i.item_name,
       l.rp_account_name,
       r.pl_code,
       decode(r.pl_code, '-1', r.fix_fee_type_code, p2.pl_name) pl_name,
       currency currency_code,
       nvl((amt * nvl(m.calc_index, 1)), 0) amt,
       'SAP' as data_source
  from if_sap_cost_sbu a
 inner join rp_profit_center_map r
    on a.profit_center_code = r.profit_center_code
   and a.bz_date = substr('20140501', 0, 6)
   and r.unit_id = 625002
 inner join rp_account_map m
    on a.account_code = m.item_code
   and m.system_type = '2' --sap
  left join rp_account_lang l
    on l.rp_account_code = m.sbu_key_code
   and l.language_code = 'en_US'
  left join bc_production_line p1
    on r.pl_code = p1.pl_code
   and p1.deleted_flag = '0'
  left join bc_production_line_lang p2
    on p1.row_id = p2.key_id
   and p2.deleted_flag = '0'
   and p2.language_code = 'en_US'
  left join bc_sap_item i
    on m.item_code = i.item_code


 

追加:

以第一种写法为例,假如如下:

select a.id, a.n a, b.n b

from tmp_1 a
left join tmp_2 b
on a.id = b.id
where b.id=...

此时SQL将正常工作,不同的时,只有表B中有的记录才会被显示出来,若B表中没有或者不符合表B的条件,则不会有任何记录。

上面的sql应该相当于:

select a.id, a.n a, b.n b

from tmp_1 a
left join tmp_2 b
on a.id = b.id

and b.id=...

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有