我希望输出为:
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
...
FY13Q3至FY14Q4与上述相同,但日期更改为与季度相匹配。关于如何使用CASE语句或GROUP BY简化此操作的任何想法?
答案 0 :(得分: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/