查看: 339|回复: 8

这个语句能否改写?

[复制链接]
论坛徽章:
307
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
发表于 2018-8-10 15:18 | 显示全部楼层 |阅读模式
ORACLE 11204

如下,红色部分的表名,是同一表,问:有无办法,去掉那个 FROM 后面的表?也就是,我只想读一遍 TM_CB_BILLMATERIALDATA 表,
该表是临时表,没法捕捉到测试数据,



MERGE INTO TM_CB_BILLMATERIALDATA t0 USING
( SELECT DISTINCT tmp.FMOENTRYID, tmp.FPPBOMENTRYID     ,
         MAX(cc.FCOSTCENTERID) FCOSTCENTERID
  FROM  TM_CB_BILLMATERIALDATA TMP
        INNER JOIN T_ENG_ROUTEOPERSEQ OPS
        ON      opS.FSEQNUMBER = tmp.FOPTQUEUE
        INNER JOIN T_ENG_ROUTEOPERDETAIL OPD
        ON(  opD.FEntryID        = opS.FEntryID
             AND opD.FOPERNUMBER = tmp.FOPERNUMBER)
        INNER JOIN T_CB_COSTCENTER CC
        ON      cc.FRELATION = opD.FDEPARTMENTID
  WHERE  ( tmp.FCOSTCENTERID = 0 AND
           (cc.FUSEORGID IN (100133) ))
  GROUP BY tmp.FMOENTRYID, tmp.FPPBOMENTRYID) t1 ON
( t1.FMOENTRYID = t0.FMOENTRYID AND t1.FPPBOMENTRYID = t0.FPPBOMENTRYID )
WHEN MATCHED THEN
        UPDATE SET t0.FCOSTCENTERID = t1.FCOSTCENTERID
论坛徽章:
312
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:22海蓝宝石
日期:2012-02-20 19:24:27铁扇公主
日期:2012-02-21 15:03:13
发表于 2018-8-10 16:47 | 显示全部楼层
这个SQL 真是个垃圾,都 GROUP BY , 还DISTINCT;
MAX的值,where里已经指定为0了。。。

update TM_CB_BILLMATERIALDATA t0
   set t0.FCOSTCENTERID = 0
where exists (
               select 'x'
                 from T_CB_COSTCENTER       cc,
                      T_ENG_ROUTEOPERDETAIL OPD,
                          T_ENG_ROUTEOPERSEQ    OPS
                where cc.FUSEORGID IN (100133)  
                  and cc.FRELATION = opD.FDEPARTMENTID
                  and opd.FEntryID = opS.FEntryID
                  and opS.FSEQNUMBER = t0.FOPTQUEUE );

使用道具 举报

回复
论坛徽章:
307
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
 楼主| 发表于 2018-8-10 17:01 | 显示全部楼层
solomon_007 发表于 2018-8-10 16:47
这个SQL 真是个垃圾,都 GROUP BY , 还DISTINCT;
MAX的值,where里已经指定为0了。。。

where里已经指定为0了。。。

你是说这个:WHERE  ( tmp.FCOSTCENTERID = 0 AND ? 不一样,

SELECT DISTINCT tmp.FMOENTRYID, tmp.FPPBOMENTRYID,
         MAX(cc.FCOSTCENTERID) FCOSTCENTERID

使用道具 举报

回复
论坛徽章:
312
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:22海蓝宝石
日期:2012-02-20 19:24:27铁扇公主
日期:2012-02-21 15:03:13
发表于 2018-8-10 17:16 | 显示全部楼层
ZALBB 发表于 2018-8-10 17:01
where里已经指定为0了。。。

你是说这个:WHERE  ( tmp.FCOSTCENTERID = 0 AND ? 不一样,

  不好意思,MAX 里面是CC , 我再看下。。。

使用道具 举报

回复
论坛徽章:
312
生肖徽章2007版:猴
日期:2008-05-16 11:28:59生肖徽章2007版:马
日期:2008-10-08 17:01:01SQL大赛参与纪念
日期:2011-04-13 12:08:17授权会员
日期:2011-06-17 16:14:53ITPUB元老
日期:2011-06-21 11:47:01ITPUB官方微博粉丝徽章
日期:2011-07-01 09:45:27ITPUB十周年纪念徽章
日期:2011-09-27 16:30:472012新春纪念徽章
日期:2012-01-04 11:51:22海蓝宝石
日期:2012-02-20 19:24:27铁扇公主
日期:2012-02-21 15:03:13
发表于 2018-8-10 17:35 | 显示全部楼层
因为你要先按TMP的连个字段对CC表先分组聚合,所以拿不掉啊,下面只是去掉了那个无效的DISTINCT:

merge into TM_CB_BILLMATERIALDATA t0
                      using (
                    select tmp.FMOENTRYID,
                               tmp.FPPBOMENTRYID,
                                                max(cc.FCOSTCENTERID) FCOSTCENTERID
                      from T_CB_COSTCENTER        cc,
                           T_ENG_ROUTEOPERDETAIL  OPD,
                           T_ENG_ROUTEOPERSEQ     OPS,
                                               TM_CB_BILLMATERIALDATA tmp
                     where cc.FUSEORGID IN (100133)  
                       and cc.FRELATION = opD.FDEPARTMENTID
                       and opd.FEntryID = opS.FEntryID
                                       and opS.FSEQNUMBER = tmp.FOPTQUEUE
                                       and tmp.FCOSTCENTERID = 0
                                     group by
                                           tmp.FMOENTRYID,
                              tmp.FPPBOMENTRYID ) t1
                      ON ( t1.FMOENTRYID = t0.FMOENTRYID AND t1.FPPBOMENTRYID = t0.FPPBOMENTRYID )
            WHEN MATCHED THEN
                 UPDATE SET t0.FCOSTCENTERID = t1.FCOSTCENTERID               

使用道具 举报

回复
论坛徽章:
527
紫蜘蛛
日期:2007-09-26 17:05:56奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:53
发表于 2018-8-10 22:08 | 显示全部楼层
你还是一贯的坏毛病,关于数据结构、表间关系、数据特征的任何信息都不提供就贴代码要人猜。
你改用相关子查询UPDATE就可以只引用一次。
如果用MERGE, 理论上讲这个两次访问当然是必需的,只是在很特殊的情况下,using里面可以把对TMP的引用去掉。

这里的DISTINCT很蠢,但是CBO会自己去掉。

使用道具 举报

回复
论坛徽章:
307
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
 楼主| 发表于 2018-8-11 12:15 | 显示全部楼层
newkid 发表于 2018-8-10 22:08
你还是一贯的坏毛病,关于数据结构、表间关系、数据特征的任何信息都不提供就贴代码要人猜。
你改用相关子 ...

你上面要的东西,除了表结构,其他的没有,语句是从EM上抓到的,TM是ORACLE的临时表,没法获取到数据,
我只想纯粹从理论上分析可行性,

使用道具 举报

回复
论坛徽章:
527
紫蜘蛛
日期:2007-09-26 17:05:56奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:53
发表于 2018-8-12 05:22 | 显示全部楼层
在一个设计良好的系统中,主外键和唯一键定义已经可以给你很多信息。
按常理猜测,这个merge是没法去掉TMP的。

使用道具 举报

回复
论坛徽章:
307
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
 楼主| 发表于 2018-8-12 10:55 | 显示全部楼层
newkid 发表于 2018-8-12 05:22
在一个设计良好的系统中,主外键和唯一键定义已经可以给你很多信息。
按常理猜测,这个merge是没法去掉TMP ...

这个我忘记说了,我们的系统里,业务数据上存在主外键关系,但系统设计上,不允许添加主外键约束。

使用道具 举报

回复

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

本版积分规则 发表回复

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