【问题标题】:What could be best possible way to avoid the intermediary tables避免中间表的最佳方法是什么
【发布时间】:2019-08-23 09:45:03
【问题描述】:

我想将一组 sql 查询转换为过程,而无需创建和删除中间表。我在下面包含了示例查询。这样做的最佳方法是什么?由于我对程序不熟悉,因此可以建议我如何做到这一点。

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

从 master_copy WHERE ZERO_BAL_CODE IN (1) 创建表 A 作为 SELECT ID_LOAN;

CREATE TABLE B AS 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 ON master_copy.ID_LOAN= A.ID_LOAN;

CREATE TABLE prepaidData AS 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 FROM B group by id_loan; alter table prepaiddata add loan_type varchar2(255) default 'prepaid';

删除表a; 删除表 b;

创建表 A 作为 SELECT ID_LOAN FROM master_copy WHERE ZERO_BAL_CODE IN (3);

CREATE TABLE B AS 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 ON master_copy.ID_LOAN= A.ID_LOAN;

CREATE TABLE DEFAULT_FORECLOSURE AS 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 FROM B group by id_loan; 改变表 DEFAULT_FORECLOSURE 添加 loan_type varchar2(255) default 'default_foreclosure';

删除表a; 删除表 b;

create table aa_loan_type as(select * from prepaiddata union select * from DEFAULT_FORECLOSURE);

【问题讨论】:

    标签: oracle oracle11g cursor procedure


    【解决方案1】:

    避免中间表的最佳方法是使用内联视图。您的查询可以重写为这条 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. 为每个内联视图使用好的名称和 cmets。您可能会想要比“A”和“B”更好的东西。
    3. 使用 Allman 风格的括号匹配,每行都有括号。内联视图很重要,需要额外的空格和对齐的括号。除了初级开发者,我们不需要像SELECT和FROM这样的关键字对齐。我们需要对齐重要的边界,比如每个内联视图的括号。这将通过在 IDE 中快速突出显示和运行代码来帮助您进行调试。
    4. 通过使用内联视图而不是相关子查询或公用表表达式来保持子查询界面的简单性。内联视图的美妙之处在于它们的简单性 - 关系数据输入,关系数据输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-12
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      • 1970-01-01
      • 2010-10-10
      • 2010-09-08
      相关资源
      最近更新 更多