什么是避免中介表的最佳方法

时间:2019-04-02 06:43:48

标签: oracle oracle11g cursor procedure

我想在不创建和删除中间表的情况下将一组sql查询转换为过程。我在下面包括了示例查询。最好的方法是什么?由于我是新手,因此程序可以为我提供建议。

我们可以在过程中使用游标吗?在查询的最后一行中,我加入了2个中间表。代替那我们可以加入两个光标吗?如果可以,我们该怎么做?有没有办法做到这一点。请给我建议。

从master_copy的WHERE ZERO_BAL_CODE IN(1)中创建表SELECT ID_LOAN;

创建表B进行选择master_copy.ID_LOAN,LOAN_AGE,master_copy.vintage,DELINQ_STATUS,ZERO_BAL_CODE,master_copy.ACTUAL_LOSS,current_upb FROM master_copy内联接ON on master_copy.ID_LOAN = A.ID_LOAN;

创建表prepaidData AS SELECT ID_LOAN,max(to_number(DELINQ_STATUS))作为DELINQ_STATUS,max(loan_age)AS LOAN_AGE,max(ZERO_BAL_CODE)作为ZERO_BAL_CODE,max(vintage)作为年份, min(ACTUAL_LOSS)为实际损失,MIN(NULLIF(current_upb,0))作为current_upb来自B组,由id_loan; 更改表prepaiddata添加loan_type varchar2(255)默认为'prepaid';

放置表a; 删除表b;

从master_copy的WHERE ZERO_BAL_CODE IN(3)中选择SELECT ID_LOAN创建表A;

创建表B进行选择master_copy.ID_LOAN,LOAN_AGE,master_copy.vintage,DELINQ_STATUS,ZERO_BAL_CODE,master_copy.ACTUAL_LOSS,current_upb FROM master_copy内联接ON on master_copy.ID_LOAN = A.ID_LOAN;

创建表DEFAULT_FORECLOSURE AS SELECT ID_LOAN,max(to_number(DELINQ_STATUS))作为DELINQ_STATUS,max(loan_age)AS LOAN_AGE,max(ZERO_BAL_CODE)作为ZERO_BAL_CODE,max(vintage)作为年份, min(ACTUAL_LOSS)为实际损失,MIN(NULLIF(current_upb,0))作为current_upb来自B组,由id_loan; 更改表DEFAULT_FORECLOSURE,添加贷款类型varchar2(255),默认为“ default_foreclosure”;

放置表a; 删除表b;

创建表aa_loan_type为(从预付费数据联合中选择*从DEFAULT_FORECLOSURE中选择*);

1 个答案:

答案 0 :(得分:2)

避免中间表的最好方法是使用内联视图。您的查询可以重写为这一条SQL语句:

--aa_loan_type
--
--prepaidData
SELECT ID_LOAN,max(to_number(DELINQ_STATUS)) as DELINQ_STATUS,max(loan_age) AS LOAN_AGE,max(ZERO_BAL_CODE) as ZERO_BAL_CODE,max(vintage) as vintage, min(ACTUAL_LOSS) as actual_loss,MIN(NULLIF(current_upb,0)) as current_upb, 'PREPAID' LOAN_TYPE
FROM
(
    --B
    SELECT
        master_copy.ID_LOAN,LOAN_AGE,master_copy.vintage,DELINQ_STATUS,ZERO_BAL_CODE,master_copy.ACTUAL_LOSS,current_upb
    FROM master_copy
    INNER JOIN
    (
        --A
        SELECT ID_LOAN FROM master_copy WHERE ZERO_BAL_CODE IN (1)
    ) A
    ON master_copy.ID_LOAN= A.ID_LOAN;
) B
GROUP BY ID_LOAN
union
--DEFAULT_FORECLOSURE
SELECT ID_LOAN,max(to_number(DELINQ_STATUS)) as DELINQ_STATUS,max(loan_age) AS LOAN_AGE,max(ZERO_BAL_CODE) as ZERO_BAL_CODE,max(vintage) as vintage, min(ACTUAL_LOSS) as actual_loss,MIN(NULLIF(current_upb,0)) as current_upb, 'default_foreclosure' loan_type
FROM 
(
    --B
    SELECT master_copy.ID_LOAN,LOAN_AGE,master_copy.vintage,DELINQ_STATUS,ZERO_BAL_CODE,master_copy.ACTUAL_LOSS,current_upb
    FROM master_copy
    INNER JOIN
    (
        --A
        SELECT ID_LOAN FROM master_copy WHERE ZERO_BAL_CODE IN (3)
    ) A
        ON master_copy.ID_LOAN= A.ID_LOAN
) B
group by id_loan;

正确构建时,一个大型SQL语句通常比多个小型SQL语句要好得多。整个代码将更简单(对象更少,在IDE中更容易调试),并且可能更快(无需编写数据,使优化器有更多机会做聪明的事情)。

“正确”地构建大型SQL是主观的,但是归结为将每个内联视图视为一个微型程序:

  1. 使每个内联视图保持简单,以简单的步骤将它们组合,然后重复。
  2. 为每个内联视图使用好名字和注释。您可能想要比“ A”和“ B”更好的东西。
  3. 使用Allman样式括号匹配,并在每行上加上括号。内联视图很重要,应保留额外的空格和对齐的括号。除初学者开发人员外,我们不需要对齐SELECTFROM之类的关键字。我们需要对齐重要边界,例如每个内联视图的括号。这将帮助您通过在IDE中快速突出显示并运行代码来进行调试。
  4. 通过使用内联视图而不是相关的子查询或公用表表达式,可以使子查询接口保持简单。内联视图的优点在于其简单性-输入关系数据,输出关系数据。