2014-07-07 164 views
2

我想輸出是:的Oracle SQL琛美元到宿舍

VENDOR_ID FY13Q1  FY13Q2  FY13Q3 FY13Q4 ... 
ABC123  5000  NULL  NULL  10000 
DEF321  10000  8000  15000  2000 

從表:

VENDOR_ID VARCHAR 
GROSS_AMT NUMERIC 
INVOICE_DT DATE 

這個查詢工作,但我需要找到一種更有效的方式(如果可能的話):

SELECT T1.VENDOR_ID, FY13Q1, FY13Q3, FY13Q4, FY14Q1, FY14Q2, FY14Q3, FY14Q4 
FROM 
( 
SELECT VENDOR_ID, SUM(GROSS_AMT) AS FY13Q1 
FROM PS_VOUCHER 
WHERE INVOICE_DT BETWEEN '01-JUL-12' AND '30-Sep-12' 
GROUP BY VENDOR_ID 
) T1 
FULL JOIN  
(  
SELECT VENDOR_ID, SUM(GROSS_AMT) AS FY13Q2 
FROM PS_VOUCHER 
WHERE INVOICE_DT BETWEEN '1-Oct-12' AND '31-Dec-12' 
GROUP BY VENDOR_ID  
) T2 
ON T1.VENDOR_ID LIKE T2.VENDOR_ID 

...

2013財年第三季度至2014財年第四季度看起來與上述相同,除了日期更改爲與季度相匹配。有關如何使用CASE語句或GROUP BY來簡化此操作的任何想法?

+1

提示:'來自DUAL的SELECT TO_CHAR(SYSDATE,'Q');' –

回答

2

原始查詢效率低下,因爲查詢使Oracle多次讀取表。幾乎所有這類問題都可以通過閱讀表格來解決。

如果您使用的是oracle 11g或更高版本,則可以使用pivot來簡化查詢。

select * from (
    select vendor_id, to_char(invoice_dt, 'yyyy-q') yyq, sum(gross_amt) amt 
    from ps_voucher 
    group by vendor_id, to_char(invoice_dt, 'yyyy-q') 
) 
pivot (
    sum(amt) 
    for yyq in ('2013-1', '2013-2', '2013-3', '2013-4', '2014-1', '2014-2', '2014-3', '2014-4') 
) 
order by vendor_id; 

如果您使用10g或以下時,你應該使用decode功能或case條款。也許你想讀這個:http://oracletuts.net/sql/three-ways-to-transpose-rows-into-columns-in-oracle-sql/