You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle最新版本中PIVOT列表限制是否仍存在?

Oracle最新版本中PIVOT列表的限制是否仍然存在?

是的,截至Oracle的最新版本(包括Oracle 21c、23c),PIVOT子句的IN列表仍要求是静态字面量集合,不支持直接通过SELECT查询动态生成列值组合。你提供的第二个查询无法执行,核心原因就是违反了这一限制——Oracle不允许在PIVOT的IN子句中嵌套SELECT * FROM T3这类动态查询来指定透视列。

可正常运行的查询

WITH DATA (A,DATE_FIELD,C,D) AS (
  SELECT 1, TO_DATE('01-JAN-2013'), 'tree',   10 FROM DUAL UNION ALL
  SELECT 1, TO_DATE('01-FEB-2013'), 'tree',   10 FROM DUAL UNION ALL
  SELECT 1, TO_DATE('20-MAR-2013'), 'world',  20 FROM DUAL UNION ALL
  SELECT 1, TO_DATE('21-APR-2013'), 'tree',   10 FROM DUAL UNION ALL
  SELECT 2, TO_DATE('21-JUN-2013'), 'tree',   30 FROM DUAL UNION ALL
  SELECT 2, TO_DATE('01-JUL-2013'), 'world',  10 FROM DUAL UNION ALL
  SELECT 2, TO_DATE('30-JUL-2013'), 'world',  20 FROM DUAL UNION ALL
  SELECT 3, TO_DATE('30-JUL-2013'), 'tree',   30 FROM DUAL UNION ALL
  SELECT 3, TO_DATE('30-JUL-2013'), 'world',  30 FROM DUAL)
SELECT * FROM (
  SELECT   A, C, TO_NUMBER(TO_CHAR (DATE_FIELD, 'd')) AS DAY, SUM(D) D
  FROM DATA
  GROUP BY A, C, TO_CHAR (DATE_FIELD, 'd')
) PIVOT ( SUM(D) FOR (A,DAY) IN (
(1, 1),(1, 2),(1, 3),(1, 4),(1, 5),(1, 6),(1, 7),(1, 8),(1, 9),(1,10),
(1,11),(1,12),(1,13),(1,14),(1,15),(1,16),(1,17),(1,18),(1,19),(1,20),
(1,21),(1,22),(1,23),(1,24),(1,25),(1,26),(1,27),(1,28),(1,29),(1,30),
(1,31),(2, 1),(2, 2),(2, 3),(2, 4),(2, 5),(2, 6),(2, 7),(2, 8),(2, 9),
(2,10),(2,11),(2,12),(2,13),(2,14),(2,15),(2,16),(2,17),(2,18),(2,19),
(2,20),(2,21),(2,22),(2,23),(2,24),(2,25),(2,26),(2,27),(2,28),(2,29),
(2,30),(2,31)
))

无法运行的查询

WITH DATA (A,DATE_FIELD,C,D) AS (
  SELECT 1, TO_DATE('01-JAN-2013'), 'tree',   10 FROM DUAL UNION ALL
  SELECT 1, TO_DATE('01-FEB-2013'), 'tree',   10 FROM DUAL UNION ALL
  SELECT 1, TO_DATE('20-MAR-2013'), 'world',  20 FROM DUAL UNION ALL
  SELECT 1, TO_DATE('21-APR-2013'), 'tree',   10 FROM DUAL UNION ALL
  SELECT 2, TO_DATE('21-JUN-2013'), 'tree',   30 FROM DUAL UNION ALL
  SELECT 2, TO_DATE('01-JUL-2013'), 'world',  10 FROM DUAL UNION ALL
  SELECT 2, TO_DATE('30-JUL-2013'), 'world',  20 FROM DUAL UNION ALL
  SELECT 3, TO_DATE('30-JUL-2013'), 'tree',   30 FROM DUAL UNION ALL
  SELECT 3, TO_DATE('30-JUL-2013'), 'world',  30 FROM DUAL),
T1 AS (SELECT ROWNUM FROM DUAL CONNECT BY ROWNUM <= 2),
T2 AS (SELECT ROWNUM FROM DUAL CONNECT BY ROWNUM <= 31),
T3 AS (SELECT * FROM T1 CROSS JOIN T2)
SELECT * FROM (
  SELECT   A, C, TO_NUMBER(TO_CHAR (DATE_FIELD, 'd')) AS DAY, SUM(D) D
  FROM DATA
  GROUP BY A, C, TO_CHAR (DATE_FIELD, 'd')
) PIVOT ( SUM(D) FOR (A,DAY) IN (SELECT * FROM T3))

替代解决方案

如你实际使用的方案,要实现动态列的透视需求,目前Oracle支持的可行方式有两种:

  • PIVOT XML:允许动态生成透视列,结果以XML格式返回,可通过XML解析函数提取所需数据
  • 动态SQL:在运行时拼接生成包含静态IN列表的PIVOT查询,这也是你当前采用的方案

内容的提问来源于stack exchange,提问作者tbc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 06:02:28