Oracle SQL Sum美元进入季度

时间:2014-07-07 23:20:54

标签: sql oracle date sum

我希望输出为:

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简化此操作的任何想法?

1 个答案:

答案 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/