有没有办法绕过Oracle交叉表PIVOT?

时间:2014-01-02 19:36:54

标签: sql oracle oracle11g pivot

我想使用AVG()函数来转移数据,但我想对结果进行舍入以防止重复显示小数。

当我尝试这样的事情时:PIVOT( ROUND( AVG(column_name), 2) FOR ...)

我收到错误:ORA-56902: expect aggregate function inside pivot operation

以下是“在课程中注册的学生人数”的一个非常简单的例子:

CREATE TABLE TBL_EXAMPLE
(
  enrolled NUMBER,
  course   VARCHAR2(50 CHAR)
);

INSERT INTO TBL_EXAMPLE (enrolled, course) VALUES (1, 'math');
INSERT INTO TBL_EXAMPLE (enrolled, course) VALUES (2, 'math');
INSERT INTO TBL_EXAMPLE (enrolled, course) VALUES (2, 'math');
INSERT INTO TBL_EXAMPLE (enrolled, course) VALUES (1, 'english');
INSERT INTO TBL_EXAMPLE (enrolled, course) VALUES (4, 'english');

SELECT * 
  FROM TBL_EXAMPLE 
 PIVOT ( AVG(enrolled) FOR course IN ('math', 'english') );

'math'          'english'
---------------|-------------
1.6666666666...| 2.5

我想要的是:

SELECT * 
  FROM TBL_EXAMPLE 
 PIVOT ( ROUND(AVG(enrolled), 2) FOR course IN ('math', 'english') );

'math'          'english'
---------------|-------------
1.67           | 2.50

在现实世界的应用程序中,SQL是基于报表上的用户输入动态生成的,由于现实世界场景的复杂性,我不能像这样重写查询:

SELECT ROUND("'math'", 2) as "'math'", ROUND("'english'", 2) as "'english'"
  FROM TBL_EXAMPLE 
 PIVOT ( AVG(enrolled) FOR course IN ('math', 'english') );

所以,我的问题是,在这种情况下,我可以使用任何解决方法来绕过ORA-56902,或者以任何其他方式将“欺骗”Oracle转换为 NOT 返回最多38位数字数字不能通过AVG()子句中的PIVOT计算均匀划分时的小数精度?

1 个答案:

答案 0 :(得分:5)

也许我错过了什么,但为什么不在带有AVG()的子查询中执行ROUND然后应用你的PIVOT:

select *
from
(
  select round(avg(enrolled), 2) enrolled, course
  from tbl_example
  group by course
) d
PIVOT 
( 
  max(enrolled) 
  FOR course IN ('math', 'english') 
);

请参阅SQL Fiddle with Demo