2013-02-20 138 views
1

我想避免使用嵌套的选定语句,如果我可以(我怀疑我会遇到性能问题)。我试图从财务交易表中获得每种类型交易的总额。我猜我可以使用同一张表中的多个选择,但是我的'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 
+0

您使用的是什么RDBMS? – valex 2013-02-20 10:29:24

回答

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