如何对具有常量/缺失列的多列使用 unpivot?
Posted
技术标签:
【中文标题】如何对具有常量/缺失列的多列使用 unpivot?【英文标题】:How to use unpivot for multiple columns with constants/missing column? 【发布时间】:2019-09-18 11:19:42 【问题描述】:我正在尝试使用 UNPIVOT 以避免多个联合的老式方式
这样做的理由是我正在收集一些数据(实验室测试、结果、单位……)我想以适当的方式显示以供审查
例如,假设我的原始数据如下所示:
ID, TESTA, RESULTA, UNITA, TESTB, RESULTB, UNITB, OTHER_UNITB
1, 'T1', 10, 1, 'T2', 2.5, , 'kg',
2, 'T1', 15, 1, 'T2', 1.5, 1, ,
3, 'T1', , , 'T2', 1, 1,
以下内容完美运行:对于每个 ID,我在每个测试中检索 1 行,并带有相应的结果和单位:
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'
)
)
;
但是,当我尝试检索特定于测试“T2”的“其他单元”时出现问题(请记住,这是一个示例,我有很多测试,差不多 20 个)
我试过了:
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'
)
)
;
对于我放在 unpivot 中的“null”语句,它失败并显示“无效标识符”消息。
我也尝试以这种方式使用常量:
....
unpivot include nulls
(
(result, unit, other_unit)
for property in (
(resulta, unita, 0) as 'T1',
(resultb, unitb, other_unitb) as 'T2'
)
)
;
这也失败了。
我被困在这里,无法弄清楚如何在不重写所有内容的情况下解决这个问题,这是一个联合声明列表 - 我想不惜一切代价避免,因为维护起来非常复杂:
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'
)
)
;
但老实说,我很惭愧这样做!
提前感谢您的支持
【问题讨论】:
你为什么对“丑陋”的解决方案感到羞耻?您生成的附加列已适当命名,并且查询很清楚它的作用;没有什么可羞耻的,它不丑,你应该使用它。 我主要关心的是我必须为常量值创建尽可能多的“伪列”。那行得通,我只是想知道是否有办法在 unpivot 子句中写入默认值/空值 【参考方案1】:您可以查看unpivot clause
的语法图。
https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_10002.htm#CHDJBHHI
它清楚地表明只有column
s 可能出现在列表中(不是文字或表达式)。
您可能需要在内联视图中创建与所需的不同常量值一样多的常量列。
作为替代方法,您可以使用老式方法:交叉连接 + 解码。
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)
【讨论】:
谢谢,至少这澄清了我的情况不能做什么!以上是关于如何对具有常量/缺失列的多列使用 unpivot?的主要内容,如果未能解决你的问题,请参考以下文章
Pandas使用split函数基于指定分隔符拆分数据列的内容为列表设置expand参数将拆分结果列表内容转化为多列dataframe(不设置参数n则列表长度不同较短的列表会出现缺失值)