Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 有没有办法进一步改进这个查询_Sql_Oracle_Query Performance - Fatal编程技术网

Sql 有没有办法进一步改进这个查询

Sql 有没有办法进一步改进这个查询,sql,oracle,query-performance,Sql,Oracle,Query Performance,我一直在学习如何使用内部连接,所以我修改了下面的查询以使用内部连接,但是我对查询的最后一个片段有问题,是否可以在那里使用内部连接?我遇到了麻烦,因为MOV是在这个片段之前完成的查询。。。有人能帮我了解如何在那里使用吗?下面的查询很有效,我只是尽可能地改进它们 片段: FROM TBLMOVOBLIGACIONES MOV1 WHERE MOV1.STRMOVANOMES = :periodo

我一直在学习如何使用内部连接,所以我修改了下面的查询以使用内部连接,但是我对查询的最后一个片段有问题,是否可以在那里使用内部连接?我遇到了麻烦,因为MOV是在这个片段之前完成的查询。。。有人能帮我了解如何在那里使用吗?下面的查询很有效,我只是尽可能地改进它们

片段:

FROM   TBLMOVOBLIGACIONES MOV1
                                  WHERE MOV1.STRMOVANOMES = :periodo
                                   AND  MOV1.STRCLINIT = MOV.STRCLINIT
                                   AND  MOV1.STROBLOBLIGSARC = MOV.STROBLOBLIGSARC
完整查询:


我想对你的这部分问题提出质疑:

 AND  NVL(MOV.STRMOVCALIFEDAD,'N') != (SELECT CASE 
                                      WHEN GREATEST(NVL(MOV1.NUMMOVNRODIASCAP,0), NVL(MOV1.NUMMOVNRODIASINT,0)) >=0 AND GREATEST(NVL(MOV1.NUMMOVNRODIASCAP,0), NVL(MOV1.NUMMOVNRODIASINT,0)) <= 30  THEN 'A'
                                      WHEN GREATEST(NVL(MOV1.NUMMOVNRODIASCAP,0), NVL(MOV1.NUMMOVNRODIASINT,0)) >=31 AND GREATEST(NVL(MOV1.NUMMOVNRODIASCAP,0), NVL(MOV1.NUMMOVNRODIASINT,0)) <= 90 THEN 'B'
                                      WHEN GREATEST(NVL(MOV1.NUMMOVNRODIASCAP,0), NVL(MOV1.NUMMOVNRODIASINT,0)) >=91 AND GREATEST(NVL(MOV1.NUMMOVNRODIASCAP,0), NVL(MOV1.NUMMOVNRODIASINT,0)) <= 180 THEN 'C'
                                      WHEN GREATEST(NVL(MOV1.NUMMOVNRODIASCAP,0), NVL(MOV1.NUMMOVNRODIASINT,0)) >=181 AND GREATEST(NVL(MOV1.NUMMOVNRODIASCAP,0), NVL(MOV1.NUMMOVNRODIASINT,0)) <= 360 THEN 'D'
                                      WHEN GREATEST(NVL(MOV1.NUMMOVNRODIASCAP,0), NVL(MOV1.NUMMOVNRODIASINT,0)) >=361 THEN 'E'
                                     END AS CALIF_CALC
                              FROM   TBLMOVOBLIGACIONES MOV1
                              WHERE MOV1.STRMOVANOMES = :periodo
                               AND  MOV1.STRCLINIT = MOV.STRCLINIT
                               AND  MOV1.STROBLOBLIGSARC = MOV.STROBLOBLIGSARC)
如果没有,那么是什么阻止该子查询返回多行,从而在运行时导致错误

您还可以一次性选择该大表达式并重用它。这是偏好的问题。看起来是这样的:

SELECT MOV.NUMPROCODIGO APLICATIVO,
       MOV.STRCLINIT NIT,
       CL.STRCLINOMBRE CLIENTE,
       MOV.STROBLOBLIGSARC OBLIGACION,
       MOV.NUMMOVVLRCAPCREDITO + MOV.NUMMOVVLRINTCREDI + MOV.NUMMOVVLRCAPOTRO SALDO_OBL,
       MOV.NUMMOVTIPOCREDITO TIPO_CREDITO,
       MOV.NUMMOVNRODIASCAP DIAS_CAP,
       MOV.NUMMOVNRODIASINT DIAS_INT,
       MOV.STRMOVCALIFEDAD,
       mov.califedad_real_expr CALIFEDAD_REAL
FROM ( SELECT mov.*,
              CASE 
                WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=0 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 30 THEN 'A'
                WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=31 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 90 THEN 'B'
                WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=91 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 180 THEN 'C'
                WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=181 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 360 THEN 'D'
                WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=361 THEN 'E'
              END AS califedad_real_expr
        FROM TBLMOVOBLIGACIONES MOV) MOV 
INNER JOIN TBLCLIENTES CL ON MOV.STRCLINIT = CL.STRCLINIT 
WHERE MOV.STRMOVANOMES = :periodo
 AND  MOV.NUMPROCODIGO NOT IN (24)
 AND MOV.NUMMOVVLRCAPCREDITO + MOV.NUMMOVVLRINTCREDI + MOV.NUMMOVVLRCAPOTRO > 0
 AND  MOV.NUMMOVTIPOCREDITO = 1
 AND  NVL(MOV.STRMOVCALIFEDAD,'N') != mov.califedad_real_expr

假设我对子查询不必要的看法是正确的

请在每篇文章中只问一个问题,这样回答起来就容易多了。另外,您能用dbfiddle发布DDL、样本数据和预期结果吗?最后,您想实现什么?您是想让代码变得更好,还是有性能问题?要研究哪个查询?完全不懂这个问题。抱歉,我将问题简化为我需要帮助改进的主要问题,我试图让它有更好的性能,也让它看起来更好,但最主要的是我如何在查询的最后一个片段上使用内部连接转换最后一个片段来使用内部连接是没有意义的,请看@Matthewmpeak的答案,它可能不会大大提高性能。
 AND  NVL(MOV.STRMOVCALIFEDAD,'N') != CASE 
                                      WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=0 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 30  THEN 'A'
                                      WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=31 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 90 THEN 'B'
                                      WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=91 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 180 THEN 'C'
                                      WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=181 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 360 THEN 'D'
                                      WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=361 THEN 'E'
                                     END
SELECT MOV.NUMPROCODIGO APLICATIVO,
       MOV.STRCLINIT NIT,
       CL.STRCLINOMBRE CLIENTE,
       MOV.STROBLOBLIGSARC OBLIGACION,
       MOV.NUMMOVVLRCAPCREDITO + MOV.NUMMOVVLRINTCREDI + MOV.NUMMOVVLRCAPOTRO SALDO_OBL,
       MOV.NUMMOVTIPOCREDITO TIPO_CREDITO,
       MOV.NUMMOVNRODIASCAP DIAS_CAP,
       MOV.NUMMOVNRODIASINT DIAS_INT,
       MOV.STRMOVCALIFEDAD,
       mov.califedad_real_expr CALIFEDAD_REAL
FROM ( SELECT mov.*,
              CASE 
                WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=0 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 30 THEN 'A'
                WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=31 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 90 THEN 'B'
                WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=91 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 180 THEN 'C'
                WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=181 AND GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) <= 360 THEN 'D'
                WHEN GREATEST(NVL(MOV.NUMMOVNRODIASCAP,0), NVL(MOV.NUMMOVNRODIASINT,0)) >=361 THEN 'E'
              END AS califedad_real_expr
        FROM TBLMOVOBLIGACIONES MOV) MOV 
INNER JOIN TBLCLIENTES CL ON MOV.STRCLINIT = CL.STRCLINIT 
WHERE MOV.STRMOVANOMES = :periodo
 AND  MOV.NUMPROCODIGO NOT IN (24)
 AND MOV.NUMMOVVLRCAPCREDITO + MOV.NUMMOVVLRINTCREDI + MOV.NUMMOVVLRCAPOTRO > 0
 AND  MOV.NUMMOVTIPOCREDITO = 1
 AND  NVL(MOV.STRMOVCALIFEDAD,'N') != mov.califedad_real_expr