楼主: dingjun123

[精华] Outer Join新旧语法对比分析

[复制链接]
论坛徽章:
10000
绿钻
日期:2016-02-22 15:43:08绿钻
日期:2016-03-01 18:19:01绿钻
日期:2016-02-22 15:43:08绿钻
日期:2016-03-01 18:19:01绿钻
日期:2015-12-16 18:42:35绿钻
日期:2015-12-11 00:18:01绿钻
日期:2015-09-10 13:05:08绿钻
日期:2015-12-11 00:18:01绿钻
日期:2015-09-10 13:05:08绿钻
日期:2015-09-10 13:05:08
11#
发表于 2010-9-4 10:42 | 只看该作者
先顶个,继续关注。。。

使用道具 举报

回复
论坛徽章:
6
ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-01-04 10:35:482011新春纪念徽章
日期:2011-02-18 11:43:332013年新春福章
日期:2013-02-25 14:51:24美羊羊
日期:2015-03-04 14:52:282015年新春福章
日期:2015-03-06 11:58:18
12#
发表于 2010-9-4 10:47 | 只看该作者
期待。。。

使用道具 举报

回复
论坛徽章:
26
2010年世界杯参赛球队:智利
日期:2010-07-03 17:16:26比亚迪
日期:2014-01-16 17:12:41宝马
日期:2014-01-24 10:32:252014年新春福章
日期:2014-02-18 16:44:08马上有对象
日期:2014-02-18 16:44:08马上有对象
日期:2014-03-05 21:30:32马上有车
日期:2014-03-11 16:46:45优秀写手
日期:2014-03-25 05:59:50马上加薪
日期:2014-03-26 16:46:30问答徽章
日期:2014-05-09 16:40:36
13#
发表于 2010-9-4 11:44 | 只看该作者
不知楼主说的结果是不是语句执行顺序问题:

scott@orcl>select e.ename,d.dname from emp e left outer join dept d on d.deptno=e.deptno and e.ename='SCOTT';

ENAME      DNAME
---------- --------------
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT      RESEARCH
KING
TURNER
ADAMS
JAMES
FORD
MILLER

已选择14行。


其实上面的语句我们主要关注下on和left outer join的执行顺序就可以理解了:
首先要知道on 是优先于left outer join先执行的
所以on过滤掉的emp表结果,最后又被left outer join拿了回来。

scott@orcl>select e.ename,d.dname from emp e left outer join dept d on e.deptno=d.deptno where e.ename='SCOTT';

ENAME      DNAME
---------- --------------
SCOTT      RESEARCH

上面的语句就不一样了,where 是在left outer join后执行的,所以是最终的过滤结果。

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
14#
 楼主| 发表于 2010-9-4 14:00 | 只看该作者
on过滤掉的emp表结果,最后又被left outer join拿了回来???
oracle不会这么傻的吧,其实无须关注顺序问题,重在基础,吉庆说的那个理解了就差不多了。
另外还涉及到outer join的算法问题,9i一般以基表为驱动表,但是到10g就不一定了,先研究基础的,使用上的注意点,然后研究下性能问题

使用道具 举报

回复
论坛徽章:
26
2010年世界杯参赛球队:智利
日期:2010-07-03 17:16:26比亚迪
日期:2014-01-16 17:12:41宝马
日期:2014-01-24 10:32:252014年新春福章
日期:2014-02-18 16:44:08马上有对象
日期:2014-02-18 16:44:08马上有对象
日期:2014-03-05 21:30:32马上有车
日期:2014-03-11 16:46:45优秀写手
日期:2014-03-25 05:59:50马上加薪
日期:2014-03-26 16:46:30问答徽章
日期:2014-05-09 16:40:36
15#
发表于 2010-9-4 14:13 | 只看该作者
记住sql语句也是由算术运算符构成的,也是有执行顺序的,详细的可以参见微软的sql server 2005 技术内幕 t-sql查询,第一章说的就是select语句的执行顺序

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
16#
 楼主| 发表于 2010-9-4 14:27 | 只看该作者
原帖由 ocpdba591 于 2010-9-4 14:11 发表
这不是傻不傻的问题,sql语句的执行顺序在这个例子中是很重要的,呵呵,我想我的sql基础还是够的


外连接中的on不需要过滤基表数据,过滤基表数据是在where里做的,on只是连接条件,根据连接条件找匹配的从表数据,找不到匹配的从表行,则置空。

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
17#
 楼主| 发表于 2010-9-4 14:28 | 只看该作者
原帖由 ocpdba591 于 2010-9-4 14:13 发表
记住sql语句也是由算术运算符构成的,也是有执行顺序的,详细的可以参见微软的sql server 2005 技术内幕 t-sql查询,第一章说的就是select语句的执行顺序

你这个顺序就是的from查询优先,然后where过滤,分组计算---》having---order by之类的吧

使用道具 举报

回复
论坛徽章:
43
生肖徽章2007版:羊
日期:2008-05-27 15:39:39铁扇公主
日期:2012-01-25 17:44:56茶鸡蛋
日期:2012-06-10 20:12:42奥运会纪念徽章:跳水
日期:2012-07-09 16:38:12奥运会纪念徽章:手球
日期:2012-07-24 08:28:36奥运会纪念徽章:艺术体操
日期:2012-09-19 13:18:16奥运会纪念徽章:柔道
日期:2012-09-26 12:34:19ITPUB 11周年纪念徽章
日期:2012-10-09 18:09:19蜘蛛蛋
日期:2012-11-06 19:43:442013年新春福章
日期:2013-02-25 14:51:24
18#
发表于 2010-9-4 16:27 | 只看该作者

回复 #18 dingjun123 的帖子

还得认真学习呀

使用道具 举报

回复
论坛徽章:
10000
绿钻
日期:2016-02-22 15:43:08绿钻
日期:2016-03-01 18:19:01绿钻
日期:2016-02-22 15:43:08绿钻
日期:2016-03-01 18:19:01绿钻
日期:2015-12-16 18:42:35绿钻
日期:2015-12-11 00:18:01绿钻
日期:2015-09-10 13:05:08绿钻
日期:2015-12-11 00:18:01绿钻
日期:2015-09-10 13:05:08绿钻
日期:2015-09-10 13:05:08
19#
发表于 2010-9-4 18:19 | 只看该作者
SQL> select * from a
  2  left join b
  3  on a.id = b.id and b.name like 'x%';


Execution Plan
----------------------------------------------------------
Plan hash value: 1365417139

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     8 |   560 |     7  (15)| 00:00:01 |
|*  1 |  HASH JOIN OUTER   |      |     8 |   560 |     7  (15)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| A    |     8 |   280 |     3   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| B    |     2 |    70 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("A"."ID"="B"."ID"(+))
   3 - filter("B"."NAME"(+) LIKE 'x%')


SQL> select * from a
  2  left join b
  3  on a.id = b.id and a.name like 'x%';


Execution Plan
----------------------------------------------------------
Plan hash value: 2608930719

----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |     8 |   560 |    27   (0)| 00:00:01 |
|   1 |  NESTED LOOPS OUTER |      |     8 |   560 |    27   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL | A    |     8 |   280 |     3   (0)| 00:00:01 |
|   3 |   VIEW              |      |     1 |    35 |     3   (0)| 00:00:01 |
|*  4 |    TABLE ACCESS FULL| B    |     1 |    35 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - filter("A"."ID"="B"."ID" AND "A"."NAME" LIKE 'x%')

-------------------------------------------
on 后面的and 条件是a.name like 还是b.name like看上去都是先过滤掉b表的数据,再做外连接?
如果是a.name like的话是否可以理解成这样条件的("A"."ID"="B"."ID" AND "A"."NAME" LIKE 'x%')
b表数据和a表做外连接?
如果是b.name like的话是否可以理解成这样条件的("A"."ID"="B"."ID" AND "B"."NAME" LIKE 'x%')
b表数据和a表做外连接?

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
20#
 楼主| 发表于 2010-9-4 18:47 | 只看该作者
第1个 1 - access("A"."ID"="B"."ID"(+))
   3 - filter("B"."NAME"(+) LIKE 'x%')
可以很容易用旧语法改写,from a,b where a.id=b.id(+) and b.name(+) like 'x%';

第2个用老语法改写就麻烦了:相当于按照连接条件到从表里找,a.id=b.id,找到了,再看匹配后的记录主表a.name是否like 'x%',如果否,则没有匹配上,从表的记录为NULL,找到就显示从表数据,用老语法改写为
   
select * from a,b where a.id=(case when a.name like 'x%' then b.id(+) end);

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表