我正在尝试使用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}}
但老实说,我为此感到羞耻!
在此先感谢您的支持
答案 0 :(得分:0)
您可以检查unpivot clause
的语法图。
https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_10002.htm#CHDJBHHI
它清楚地表明,列表中只能出现column
(而不是文字或表达式)。
您可能需要在内联视图中创建尽可能多的 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)