Reg:Oracle中的查询更改

koaltpgm  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(141)

我是Oracle的新手,正在学习课程,遇到了一些阻碍。我有下面的查询,其中ddetl表由于编写的内部查询逻辑而减慢了查询速度。我想知道是否有任何方法可以进行更改,以便在选择ddetl记录时不使用OR条件。
我只能想到使查询作为动态查询,但我不认为这是一个有效的想法。你能告诉我该怎么办吗?(不期望查询是为我写的,只是想要一个想法)。

SELECT 1,
       rcd.id,
       sr.id ,
       rcd.crit_seq,
       rcd.ev_id,
       null,
       dd.funds_avail_date,
       sr.action_allowed,
       dd.dsba_id,
       decode(sr.detl_level,'Y',dd.seqnbr,null),
       dd.ga_id
  FROM rc_detail   rcd,
       ddetl       dd,
       sr_crit     src,
       srule       sr,
       sr_type     rt
 WHERE rt.id = sr.rule_type
   and sr.id = rcd.std_rl_id
   and src.std_rl_id = sr.id
   and rcd.std_rl_id = src.std_rl_id
   and rcd.crit_seq = src.seqnbr
   and src.crit_type = 'STD'
   and ((nvl(sr.detl_level,'N') != 'Y'
          and (dd.dsba_id,dd.ga_id,dd.seqnbr) in
              (SELECT MIN(dsba_id),MIN(ga_id), MIN(seqnbr)
                  FROM   ddetl
                 WHERE  dsba_id = v_dsba_id
                   AND  ga_id = v_ga_id))
           OR (sr.detl_level = 'Y'
               and dd.dsba_id = v_dsba_id
               and dd.ga_id = v_ga_id))
 and rt.id = 'LOAN-SPEC'
 and nvl(rcd.irs_code,'xxxxx') = 'xxxxx'
 and nvl(rcd.dsrs_code,'xxxxx') = 'xxxxx'
 and nvl(rcd.dsmd_code,'xxxxx') = 'xxxxx'
 and nvl(rcd.sdio_id,dd.sdio_id) = dd.sdio_id
 and nvl(rcd.sdmt_code,dd.sdmt_code) = dd.sdmt_code
 and (nvl(rcd.gaio_qual,dd.gaio_qual) = dd.gaio_qual OR
         dd.gaio_qual is null)
 and (nvl(rcd.gdmt_seqnbr,dd.gdmt_seqnbr) = dd.gdmt_seqnbr OR
         dd.gdmt_seqnbr is null);

我尝试使用“with as”查询进行更改,但它不起作用,或者我无法进行更改,以便查询可以工作。
下面是我想改变的逻辑。

and ((nvl(sr.detl_level,'N') != 'Y'
          and (dd.dsba_id,dd.ga_id,dd.seqnbr) in
              (SELECT MIN(dsba_id),MIN(ga_id), MIN(seqnbr)
                 FROM   ddetl
                WHERE  dsba_id = v_dsba_id
                  AND  ga_id = v_ga_id))
            OR (sr.detl_level = 'Y'
               and dd.dsba_id = v_dsba_id
               and dd.ga_id = v_ga_id))
dpiehjr4

dpiehjr41#

对于一个刚接触Oracle的人,我建议你阅读一些更多关于选择和连接表的基本规则的文档。您正在使用的join sintax已经停用了30年。尝试给予别名,以您所选择的列不结束了“列模棱两可的定义”错误。对不起,但是如果没有一些示例数据和没有预期结果,几乎不可能帮助您的代码。我试图重写它看起来像它可以工作。我盲目地做了它,它不会工作,但也许你可以得到一些想法,如何使它与您的实际数据工作。但是,在您的代码中有两个来源不明的标识符,我不知道该如何处理(v_dsba_id和v_ga_id)。下面是代码(带有一些注解),可以帮助您找到摆脱困境的方法:

Select      1 "SOME_NUMBER_COLUMN",     --  all columns now have aliases
            rcd.id "RCD_ID",
            sr.id "SR_ID",
            rcd.crit_seq "CRIT_SEQ",
            rcd.ev_id "EV_ID",
            Null "SOME_NULL_COLUMN",
            dd.funds_avail_date "FUNDS_DATE",
            sr.action_allowed "ACTION_ALLOWED",
            dd.dsba_id "DSBA_ID",
            Decode(sr.detl_level, 'Y', dd.seqnbr, Null) "DETL_LEVEL_OR_SEQNBR",
            dd.ga_id "GA_ID"
From        rc_detail rcd                       -- tables Inner or Left joind by ON() conditions
--
Inner Join  sr_crit src ON  (   src.std_rl_id = rcd.std_rl_id And 
                                src.seqnbr = rcd.crit_seq And
                                src.crit_type = 'STD'       )  -- nothing selected from sr_crit - could be a filter ('STD')
--
Inner Join  srule sr ON( sr.id = rcd.std_rl_id )
--
Inner Join  sr_type rt ON(rt.id = sr.rule_type And rt.id = 'LOAN-SPEC') -- nothing selected from sr_type - could be a filter ('LOAN-SPEC')
--
Inner Join  ddetl dd ON (   dd.sdio_id = Nvl(rcd.sdio_id, dd.sdio_id) And 
                            dd.sdmt_code = Nvl(rcd.sdmt_code, dd.sdmt_code) And 
                            (   dd.gaio_qual = Nvl(rcd.gaio_qual, dd.gaio_qual) OR dd.gaio_qual is null ) And 
                            (   dd.gdmt_seqnbr = Nvl(rcd.gdmt_seqnbr, dd.gdmt_seqnbr) OR dd.gdmt_seqnbr is null ) 
                        )
--
Left Join   (   Select  MIN(dsba_id) "MIN_DSBA_ID", 
                        MIN(ga_id) "MIN_GA_ID", 
                        MIN(seqnbr) "MIN_SEQNBR" 
                From    ddetl 
                Where   dsba_id = v_dsba_id And     --  WHAT is v_dsba_id 
                        ga_id = v_ga_id             --  WHAT is v_ga_id
            ) dd2 ON(   dd2.MIN_DSBA_ID = dd.dsba_id And 
                        dd2.MIN_GA_ID = dd.ga_id And 
                        dd2.MIN_SEQNBR = dd.seqnbr And   
                    )
Where   COALESCE(rcd.irs_code, rcd.dsrs_code, rcd.dsmd_code) Is Null And    -- COALESCE() function instead of tripple Nulls converted to 'xxxx'
        (   
            ( dd2.MIN_DSBA_ID Is Not Null And Nvl(sr.detl_level, 'N') != 'Y' )
          OR
            ( dd.dsba_id = v_dsba_id And dd.ga_id = v_ga_id And sr.detl_level = 'Y' )   --  WHAT are v_dsba_id and v_ga_id
        )

再一次,这只是一个盲目的尝试猜测什么是真正发生的-这段代码将无法工作,没有你的干预.

相关问题