2013-02-20 4 views
1

Я бы хотел избежать использования вложенного выбранного оператора, если могу (я подозреваю, что я столкнулся с проблемами производительности). Я пытаюсь получить общую сумму для каждого типа транзакций из таблицы финансовых транзакций. Я предполагаю, что могу использовать несколько выборок из одной таблицы, но мои цифры «BFWD» возвращают свои результаты на "bil_yer + 1" (а не только на необработанные bil_yer). Любые предложения будут ценны.Альтернатива вложенному оператору select

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

Какие СУБД вы используете? – valex

ответ

0

Вы не упомянули 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