Oracle Pivot 中的 Null 替换 Table

Null Replacement in Oracle Pivot Table

我目前正在使用以下代码来旋转 table,它运行良好。现在我想在求和后用 'No Data' 替换任何空值,但出现错误,所以我认为我将 case 语句放在了错误的位置。

这个有效:

SELECT *
FROM   (SELECT PROV_NO, DATA_YEAR, DATA_MONTH, MEASURE_ID, CASES
    FROM   pivot_test_2)
PIVOT  (SUM(CASES) FOR (MEASURE_ID) IN ('MORT_30_AMI', 'MORT_30_HF', 'MORT_30_PN'))
order by PROV_NO, DATA_YEAR, DATA_MONTH;

但这并不

SELECT *
FROM   (SELECT PROV_NO, DATA_YEAR, DATA_MONTH, MEASURE_ID, CASES
    FROM   pivot_test_2)
PIVOT  (SUM(CASES) FOR (MEASURE_ID) IN ('MORT_30_AMI', 'MORT_30_HF', 'MORT_30_PN'))
case when MORT_30_HF is null then 'No Data' else MORT_30_HF end
order by PROV_NO, DATA_YEAR, DATA_MONTH;    

我得到 "ORA-00933: SQL command not properly ended" 作为错误。我正在尝试放置“;”周围,​​但错误仍然相同。我目前在使用 Oracle 11g 并使用 Golden 作为我的 scripting/retrieval 软件。

您可以将 CASE 语句移动到 SELECT 语句并在那里处理 NULL 值。更好的是,使用 COALESCE。但不幸的是,您必须对 SELECT 列表中的每个项目执行此操作:

SELECT
       --Must manually reference each column.
       COALESCE(TO_CHAR(MORT_30_AMI), 'No Data') MORT_30_AMI,
       COALESCE(TO_CHAR(MORT_30_HF), 'No Data') MORT_30_HF,
       COALESCE(TO_CHAR(MORT_30_PN), 'No Data') MORT_30_PN,
       PROV_NO, DATA_YEAR, DATA_MONTH
FROM   (SELECT PROV_NO, DATA_YEAR, DATA_MONTH, MEASURE_ID, CASES
        FROM   pivot_test_2)
PIVOT 
       (
          SUM(CASES)
          FOR (MEASURE_ID) IN
          --Use aliases to make the columns easier to use.
          ('MORT_30_AMI' MORT_30_AMI, 'MORT_30_HF' MORT_30_HF, 'MORT_30_PN' MORT_30_PN))
ORDER BY PROV_NO, DATA_YEAR, DATA_MONTH;

一个不起作用的简单版本

理想情况下,您可以替换这部分代码:

SUM(CASES)

有了这个:

COALESCE(TO_CHAR(SUM(CASES)), 'No data')

那么您就不需要分别处理每一列。但是似乎没有办法自动将非聚合函数应用于 PIVOT 的结果。使用上面的代码会生成此错误消息:

ORA-56902: expect aggregate function inside pivot operation

示例架构

create table pivot_test_2
(
  PROV_NO CHAR(6),
  DATA_YEAR NUMBER(4),
  DATA_MONTH Number(2),
  MEASURE_ID VARCHAR2(250),
  CASES NUMBER
);

insert into pivot_test_2
select 'A', 2000, 1, 'MORT_30_AMI', 1 from dual union all
select 'A', 2000, 1, 'MORT_30_AMI', 1 from dual union all
select 'A', 2000, 1, 'MORT_30_HF',  2 from dual union all
select 'A', 2000, 1, 'MORT_30_HF',  2 from dual;

谢谢大家,在大家的帮助下,我终于把它拼凑起来了,而且很管用。

SELECT PROV_NO, DATA_YEAR, DATA_MONTH,
case when MORT_30_AMI is null then 'No Data' else to_char(MORT_30_AMI) end as MORT_30_AMI,
case when MORT_30_HF is null then 'No Data' else to_char(MORT_30_HF) end as MORT_30_HF,
case when MORT_30_PN is null then 'No Data' else to_char(MORT_30_PN) end as MORT_30_PN
    FROM  pivot_test_2
PIVOT  (SUM(CASES) FOR (MEASURE_ID) IN ('MORT_30_AMI' as MORT_30_AMI,'MORT_30_HF' as MORT_30_HF, 'MORT_30_PN' as MORT_30_PN))
order by PROV_NO, DATA_YEAR, DATA_MONTH;

对查询定义字段(来自数据透视表定义字段列表)使用 DECODE 关键字,然后将 NULL 替换为您需要的任何值。即,用 'No Data' 代替 NULL。我相信应该可以解决这个问题。