替代嵌套的select语句

时间:2013-02-20 09:59:08

标签: performance select nested

如果可以的话,我想避免使用嵌套的选定语句(我怀疑我会遇到性能问题)。我正试图从金融交易表中获得每种交易类型的总额。我猜我可以使用同一个表中的多个选项但是我的'BFWD'数字会将结果返回"bil_yer + 1"(而不仅仅是原始bil_yer)。任何建议都将不胜感激。

SELECT bil_yer,
    acc_num,
    ubsgch_key_num,
    sum(bfw_arr) AS bfw_arr,
    sum(bfw_int) AS bfw_int,
    sum(ytd_chg) AS ytd_chg,
    sum(ytd_och) AS ytd_och
FROM (
    -- BFWD Charges
    SELECT src_bil_yer + 1 AS bil_yer,
        src_acc_num AS acc_num,
        des_ubsgch_key_num AS ubsgch_key_num,
        src_trn_amt AS bfw_arr,
        0 AS bfw_int,
        0 AS ytd_chg,
        0 AS ytd_och
    FROM av_ub_tran
    WHERE src_trn_cde <> 2601

    UNION ALL -- BFWD Interest
    SELECT src_bil_yer + 1 AS bil_yer,
        src_acc_num AS acc_num,
        des_ubsgch_key_num AS ubsgch_key_num,
        0 AS bfw_arr,
        src_trn_amt AS bfw_int,
        0 AS ytd_chg,
        0 AS ytd_och
    FROM av_ub_tran
    WHERE src_trn_cde = 2601

    UNION ALL -- YTD Current Charges - Raised in the current year but NOT past due
    SELECT src_bil_yer AS bil_yer,
        src_acc_num AS acc_num,
        des_ubsgch_key_num AS ubsgch_key_num,
        0 AS bfw_arr,
        0 AS bfw_int,
        src_trn_amt AS ytd_chg,
        0 AS ytd_och
    FROM av_ub_tran
    WHERE src_trn_cde = 2600
      AND src_due_dte >= 'TODAY'

    UNION ALL -- YTD Current Overdue Charges - Raised in the current year but PAST due
    SELECT src_bil_yer AS bil_yer,
        src_acc_num AS acc_num,
        des_ubsgch_key_num AS ubsgch_key_num,
        0 AS bfw_arr,
        0 AS bfw_int,
        0 AS ytd_chg,
        src_trn_amt AS ytd_och
    FROM av_ub_tran
    WHERE src_trn_cde = 2600
      AND src_due_dte < 'TODAY'
)
GROUP BY
    bil_yer,
    acc_num,
    ubsgch_key_num

1 个答案:

答案 0 :(得分:0)

您没有提到您使用的RDBMS,但大多数RDBMS都有CASE statement。你可以使用它。您在第一个子查询中使用src_bil_yer + 1,它是group by字段,因此您无论如何都必须使用嵌套查询。 请尝试以下查询:

SELECT 
    bil_yer,
    acc_num,
    ubsgch_key_num,
    sum(bfw_arr) AS bfw_arr,
    sum(bfw_int) AS bfw_int,
    sum(ytd_chg) AS ytd_chg,
    sum(ytd_och) AS ytd_och
FROM (
    SELECT src_bil_yer + 1 AS bil_yer,
        src_acc_num AS acc_num,
        des_ubsgch_key_num AS ubsgch_key_num,
        CASE WHEN src_trn_cde <> 2601 THEN src_trn_amt ELSE 0 END AS bfw_arr,
        CASE WHEN src_trn_cde = 2601 THEN src_trn_amt ELSE 0 END AS bfw_int,
        0 AS ytd_chg,
        0 AS ytd_och
    FROM av_ub_tran

    UNION ALL 
    SELECT src_bil_yer AS bil_yer,
        src_acc_num AS acc_num,
        des_ubsgch_key_num AS ubsgch_key_num,
        0 AS bfw_arr,
        0 AS bfw_int,
        CASE WHEN src_due_dte >= 'TODAY' THEN src_trn_amt ELSE 0 END AS ytd_chg,
        CASE WHEN src_due_dte <  'TODAY' THEN src_trn_amt ELSE 0 END AS ytd_och
    FROM av_ub_tran
    WHERE src_trn_cde = 2600
)
GROUP BY
    bil_yer,
    acc_num,
    ubsgch_key_num