如何对带有常量/缺失列的多列使用unpivot?

时间:2019-09-18 11:19:42

标签: sql oracle unpivot

我正在尝试使用UNPIVOT,以避免使用老式的多工会方式

这样做的理由是我正在收集一些数据(实验室测试,结果,单位等),我希望以适当的方式显示这些数据以供查阅

例如,假设我的原始数据如下:

select  id,
        property as test_code,
        decode(property, 'T1', 'Test 01', 'T2', 'Test 02', 'Unknown test') as test_name,
        result,
        unit
from    my_table
unpivot include nulls
        (
            (result, unit)
            for property in (
              (resulta, unita) as 'T1',
              (resultb, unitb) as 'T2'
            )
        )
;

以下内容非常适用:对于每个ID,我为每个测试检索1行以及相应的结果和单位:

select  id,
        property as test_code,
        decode(property, 'T1', 'Test 01', 'T2', 'Test 02', 'Unknown test') as test_name,
        result,
        unit,
        other_unit
from    my_table
unpivot include nulls
        (
            (result, unit, other_unit)
            for property in (
              (resulta, unita, null) as 'T1',
              (resultb, unitb, other_unitb) as 'T2'
            )
        )
;

但是,当我尝试检索特定于测试“ T2”的“其他单元”时,事情就出错了(请记住,这是一个示例,我已经进行了将近20项测试)

我尝试过:

....
unpivot include nulls
        (
            (result, unit, other_unit)
            for property in (
              (resulta, unita, 0) as 'T1',
              (resultb, unitb, other_unitb) as 'T2'
            )
        )
;

它失败,并在消息中输入“ null”语句时显示消息“无效标识符”。

我也尝试以这种方式使用常量:

select resulta as result,
       unita as unit,
       null as other_unit
from   my_table
union
select resultb as result,
       unitb as unit,
       other_unitbas other_unit
from   my_table
union
...

那也失败了。

我被困在这里,在不重新编写所有内容的情况下,不知道如何解决这个问题,这是联合声明的列表-我想不惜一切代价避免,因为维护起来很复杂:

select  id,
        property as test_code,
        decode(property, 'T1', 'Test 01', 'T2', 'Test 02', 'Unknown test') as test_name,
        result,
        unit,
        other_unit
from    (
            select  m.*,
                    null as null_item
            from    my_table m
        )

unpivot include nulls
        (
            (result, unit, other_unit)
            for property in (
              (resulta, unita, null_item) as 'T1',
              (resultb, unitb, other_unitb) as 'T2'
            )
        )
;

我也找到了一个丑陋的解决方案:

{{1}}

但老实说,我为此感到羞耻!

在此先感谢您的支持

1 个答案:

答案 0 :(得分:0)

您可以检查unpivot clause的语法图。

https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_10002.htm#CHDJBHHI

它清楚地表明,列表中只能出现column(而不是文字或表达式)。 enter image description here

您可能需要在内联视图中创建尽可能多的 distinct 常量值。

作为一种替代方法,您可以使用老式方法:交叉连接+解码。

select id,
       test_code,
       decode(test_code, 'T1', 'Test 01', 'T2', 'Test 02', 'Unknown test') as test_name,
       decode(test_code, 'T1', resulta, 'T2', resultb) result,
       decode(test_code, 'T1', unita, 'T2', unitb) unit,
       decode(test_code, 'T2', other_unitb) other_unit
  from my_table t,
       (select 'T' || level test_code from dual connect by level <= 2)