我有一张这样的表:
initial confirmatory confirmatory1 confirmatory2 confirmatory3
3.4 true 3.6 4.9 7.4
2.1 false null null null
我想生成这样的数据库视图:
initial confirmatory_n confirmatory_value
3.4 1 3.6
3.4 2 4.9
3.4 3 7.4
2.1 null 2.1
对于confirmatory
为false的行,我需要显示第1行。对于confirmatory
为true的行,我需要在三个不同的行中显示3次数据,并使用额外的列标识显示的值。
我一直在搜索,但似乎无法找到相关结果。在尝试展示confirmatory_n
时,我总是陷入困境。所以,我真的没有一个没有工作的sql样本,因为我觉得我离我很远。但是,我确实创建了一个可能有帮助的sqlfiddle。任何帮助都会很棒。
我使用的是Oracle 11g。
答案 0 :(得分:2)
另一个UNPIVOT解决方案:
WITH src ("INITIAL", confirmatory, confirmatory1, confirmatory2, confirmatory3) as (
SELECT 3.4, 'true', 3.6, 4.9, 7.4 FROM DUAL UNION ALL
SELECT 2.1, 'false', NULL, NULL, NULL FROM DUAL
), dta as (
select "INITIAL"
, case upper(confirmatory) when 'FALSE' then "INITIAL" end confirmatory
, confirmatory1
, confirmatory2
, confirmatory3
from src
)
select *
from dta
unpivot (confirmatory_value
FOR confirmatory_n IN (CONFIRMATORY AS null,
CONFIRMATORY1 AS 1,
CONFIRMATORY2 AS 2,
CONFIRMATORY3 AS 3));
答案 1 :(得分:1)
使用union all
:
select initial_value, 1 as confirmatory_n, confirmatory1 as confirmatory
from results t
where confirmatory = 1
union all
select initial_value, 2 as confirmatory_n, confirmatory2 as confirmatory
from results t
where confirmatory = 1
union all
select initial_value, 3 as confirmatory_n, confirmatory3 as confirmatory
from results t
where confirmatory = 1
union all
select initial_value, null as confirmatory_n, initial_value
from results t
where confirmatory = 0;
SQL小提琴是here。 如果您的表非常大并且性能是一个问题,那么还有其他方法只扫描一次表。但是,这种方法通常就足够了。
答案 2 :(得分:1)
UNPIVOT解决方案
WITH src ("INITIAL", confirmatory, confirmatory1, confirmatory2, confirmatory3) as (
SELECT 3.4, 'true', 3.6, 4.9, 7.4 FROM DUAL UNION ALL
SELECT 2.1, 'false', NULL, NULL, NULL FROM DUAL
)
SELECT
"INITIAL",
confirmatory_n,
confirmatory_value
FROM (
SELECT
"INITIAL",
CASE WHEN confirmatory_value IS NOT NULL THEN confirmatory_n END confirmatory_n,
CASE WHEN confirmatory_value IS NOT NULL THEN confirmatory_value ELSE "INITIAL" END confirmatory_value
FROM
src
UNPIVOT INCLUDE NULLS (
confirmatory_value FOR confirmatory_n IN (confirmatory1 AS 1, confirmatory2 AS 2, confirmatory3 AS 3)
)
)
GROUP BY
"INITIAL",
confirmatory_n,
confirmatory_value
ORDER BY
confirmatory_n;
答案 3 :(得分:0)
这可能不是最有效的解决方案(特别是 n 的任意值),但您可以编写一系列UNION
选项来完成此任务。适用于Oracle 12c。
编辑:编辑以适合您的小提琴。
Edit2:我的解决方案需要UNION ALL
性能更高。union
过滤掉确认错误的重复行。 union all
解决方案会更高效。
select initial_value,
case when (confirmatory = 1 and confirmatory1 is not null) then '1' else null end confirmatory_n,
case when (confirmatory = 1 and confirmatory1 is not null) then confirmatory1 else initial_value end confirmatory_value
from results
UNION
select initial_value,
case when (confirmatory = 1 and confirmatory2 is not null) then '2' else null end confirmatory_n,
case when (confirmatory = 1 and confirmatory2 is not null) then confirmatory2 else initial_value end confirmatory_value
from results
UNION
select initial_value,
case when (confirmatory = 1 and confirmatory3 is not null) then '3' else null end confirmatory_n,
case when (confirmatory = 1 and confirmatory3 is not null) then confirmatory3 else initial_value end confirmatory_value
from results