有没有办法改进更多这个查询
Is there a way to improve more this query
我一直在学习如何使用 INNER JOIN,所以我修改了以下查询以使用 inner join,但是我在查询的最后一个片段上遇到了问题,是否可以在那里使用 inner join?我遇到了麻烦,因为“MOV”是在此片段之前完成的查询...有人可以帮助我了解如何在那里使用吗?以下查询有效,尽我所能改进它们
片段:
FROM TBLMOVOBLIGACIONES MOV1
WHERE MOV1.STRMOVANOMES = :periodo
AND MOV1.STRCLINIT = MOV.STRCLINIT
AND MOV1.STROBLOBLIGSARC = MOV.STROBLOBLIGSARC
完整查询:
SELECT * FROM (
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,
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
FROM TBLMOVOBLIGACIONES 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') != (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)
我会质疑你的这部分查询:
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)
要么 (strmovanomes, strclinit, stroblobligsarc)
包含(或恰好是)tblmovobligaciones
的主键,要么不包含。
If if does,则子查询正在查询 tblmovobligaciones
中您已有的同一行。在这种情况下,应删除子查询并将条件替换为:
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 那个大表达式一次并重复使用它。这是一个偏好问题。看起来像这样:
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
(假设我认为子查询是不必要的是对的)
我一直在学习如何使用 INNER JOIN,所以我修改了以下查询以使用 inner join,但是我在查询的最后一个片段上遇到了问题,是否可以在那里使用 inner join?我遇到了麻烦,因为“MOV”是在此片段之前完成的查询...有人可以帮助我了解如何在那里使用吗?以下查询有效,尽我所能改进它们
片段:
FROM TBLMOVOBLIGACIONES MOV1
WHERE MOV1.STRMOVANOMES = :periodo
AND MOV1.STRCLINIT = MOV.STRCLINIT
AND MOV1.STROBLOBLIGSARC = MOV.STROBLOBLIGSARC
完整查询:
SELECT * FROM (
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,
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
FROM TBLMOVOBLIGACIONES 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') != (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)
我会质疑你的这部分查询:
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)
要么 (strmovanomes, strclinit, stroblobligsarc)
包含(或恰好是)tblmovobligaciones
的主键,要么不包含。
If if does,则子查询正在查询 tblmovobligaciones
中您已有的同一行。在这种情况下,应删除子查询并将条件替换为:
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 那个大表达式一次并重复使用它。这是一个偏好问题。看起来像这样:
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
(假设我认为子查询是不必要的是对的)