Oracle中SQL优化:left join查询语句,多个字段关联同一个表问题

杨友山
博客专家认证
2014-08-04 02:21:17

tabA表,
此表字段:
code1,code2,code3

tabB表:
此表字段:
id,code,codeName

查询:
select
b1.codeName,
b2.codeName,
b3.codeName
from tabA a
left join tabB b1
on a.code1=b1.code

left join tabB b2
on a.code2=b2.code

left join tabB b3
on a.code3= b3.code

where 1=1


这种查询,对于tabB表扫描次数太频繁,请问如何更改比较合理。
...全文
13287 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
coderLee0607 2016-05-30
  • 打赏
  • 举报
回复
遇到了同样的问题,楼主解决了吗?
爱吃鱼的猫^_^ 2016-03-25
  • 打赏
  • 举报
回复
楼主解决了吗,分享下
xpstrive 2015-12-30
  • 打赏
  • 举报
回复
select * from a left join b on a.id = b.id and a.name = b.name and a.whatever = b.whatever
Ellison 2015-03-30
  • 打赏
  • 举报
回复
这个问题也困扰了我很久,可不可以建一个物化视图将这个结果集存起来,以后直接查物化视图。
yuyeyi 2014-08-22
  • 打赏
  • 举报
回复
引用 14 楼 yuyeyi 的回复:
[quote=引用 13 楼 bw555 的回复:] [quote=引用 12 楼 yuyeyi 的回复:]

select 
(case when a.code1=b1.code then b1.codename end),
(case when a.code1=b1.code then b1.codename end),
(case when a.code1=b1.code then b1.codename end)
from tabA a
left join tabB b1
on (a.code1=b1.code or a.code2=b1.code or a.code3= b1.code)
此方法不可取 取出的结果会一条变三条,如 C1NAME NULL NULL NULL C2NAME NULL NULL NULL C3NAME[/quote]


select 
(case when a.code1=b1.code then b1.codename end),
(case when a.code2=b1.code then b1.codename end),
(case when a.code3=b1.code then b1.codename end)
from tabA a
left join tabB b1
on (a.code1=b1.code or a.code2=b1.code or a.code3= b1.code)


[/quote] select max(case when a.code1=b.code then b.CODNAME end), max(case when a.code2=b.code then b.CODNAME end), max(case when a.code3=b.code then b.CODNAME end) from a left join b on a.code1=b.code or a.code2=b.code or a.code3= b.code group by a.rowid
  • 打赏
  • 举报
回复

--如果满足要求的话 楼主看看这个
SELECT code1, code2, code3, wm_concat(t2.name)
  FROM t t1
  LEFT JOIN tb t2
    ON (t1.code1 = t2.code OR t1.code2 = t2.code OR t1.code3 = t2.code)
 GROUP BY code1, code2, code3

美到心痛 2014-08-21
  • 打赏
  • 举报
回复
4楼的方法可以测一下,速度有没有提升. 楼主原本的语句,如果每次经过where筛选后,数据量不大,在tabB的code上加个索引就差不多了
yuyeyi 2014-08-21
  • 打赏
  • 举报
回复
引用 13 楼 bw555 的回复:
[quote=引用 12 楼 yuyeyi 的回复:]

select 
(case when a.code1=b1.code then b1.codename end),
(case when a.code1=b1.code then b1.codename end),
(case when a.code1=b1.code then b1.codename end)
from tabA a
left join tabB b1
on (a.code1=b1.code or a.code2=b1.code or a.code3= b1.code)
此方法不可取 取出的结果会一条变三条,如 C1NAME NULL NULL NULL C2NAME NULL NULL NULL C3NAME[/quote]


select 
(case when a.code1=b1.code then b1.codename end),
(case when a.code2=b1.code then b1.codename end),
(case when a.code3=b1.code then b1.codename end)
from tabA a
left join tabB b1
on (a.code1=b1.code or a.code2=b1.code or a.code3= b1.code)


bw555 2014-08-21
  • 打赏
  • 举报
回复
引用 12 楼 yuyeyi 的回复:

select 
(case when a.code1=b1.code then b1.codename end),
(case when a.code1=b1.code then b1.codename end),
(case when a.code1=b1.code then b1.codename end)
from tabA a
left join tabB b1
on (a.code1=b1.code or a.code2=b1.code or a.code3= b1.code)
此方法不可取 取出的结果会一条变三条,如 C1NAME NULL NULL NULL C2NAME NULL NULL NULL C3NAME
yuyeyi 2014-08-21
  • 打赏
  • 举报
回复

select 
(case when a.code1=b1.code then b1.codename end),
(case when a.code1=b1.code then b1.codename end),
(case when a.code1=b1.code then b1.codename end)
from tabA a
left join tabB b1
on (a.code1=b1.code or a.code2=b1.code or a.code3= b1.code)

不写代码的钦 2014-08-21
  • 打赏
  • 举报
回复
引用 8 楼 yysyangyangyangshan 的回复:
这很简单嘛,比如一个单据表有 批准人,审核人,复审核人 而这些人肯定都是对应的员工表。那么查询的时候自然就要关联一下,只是这个sql关联的有些多了。
要么重新设计表,要么行列转换。
xinpingf 2014-08-04
  • 打赏
  • 举报
回复
b表很大吗?b.code应该有唯一索引的吧,这样应该问题也不大
  • 打赏
  • 举报
回复
引用 8 楼 yysyangyangyangshan 的回复:
这很简单嘛,比如一个单据表有 批准人,审核人,复审核人 而这些人肯定都是对应的员工表。那么查询的时候自然就要关联一下,只是这个sql关联的有些多了。
如果是这样的表,考虑一下改成由person_name,person_identity和document_id三个字段组成的表如何,类似的你的表也可以改改嘛。只是个想法,可以试试
杨友山 2014-08-04
  • 打赏
  • 举报
回复
这很简单嘛,比如一个单据表有 批准人,审核人,复审核人 而这些人肯定都是对应的员工表。那么查询的时候自然就要关联一下,只是这个sql关联的有些多了。
IT_lau 2014-08-04
  • 打赏
  • 举报
回复
这是要干嘛,看着都不通
bw555 2014-08-04
  • 打赏
  • 举报
回复
引用 5 楼 u012999424 的回复:
表A设计的意义是什么
估计又是某个前辈为后辈维护人员遗留的问题吧
  • 打赏
  • 举报
回复
表A设计的意义是什么
bw555 2014-08-04
  • 打赏
  • 举报
回复
列转行,再行转列,B表访问次数少了 但是至于那个执行时间快,不确定,具体执行下或看一下执行计划吧
SELECT MAX(DECODE(A.CONAME,'code1',B.codeName)),
     MAX(DECODE(A.CONAME,'code2',B.codeName)),
     MAX(DECODE(A.CONAME,'code3',B.codeName))
FROM
   (select code1 as code,'code1' as colname,rowid as id from TABLEA
   union all
   select code2 as code,'code2' as colname,rowid as id from TABLEA
   union all
   select code3 as code,'code3' as colname,rowid as id from TABLEA) A,TABLEB B
WHERE A.CODE=B.CODE
GROUP BY A.ID
杨友山 2014-08-04
  • 打赏
  • 举报
回复
引用 2 楼 u012999424 的回复:
表A三个字段看起来好像一样啊,为什么不用一个字段就行?
不能的, 比如 那个三个字段是:中国,美国,英国 B表则是国家表。
  • 打赏
  • 举报
回复
表A三个字段看起来好像一样啊,为什么不用一个字段就行?
加载更多回复(1)

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧