将行的值复制到具有相同键的列中

时间:2017-03-10 10:05:08

标签: sql oracle

我必须将key1作为区别列来应用以下转换。

输入数据

key1 key2 value
1    val1    x
1    val2    y
2    val1    x
2    val2    z
3    val2    z
4    val1    x
4    val2    y
4    val2    z

输出

key1 val1 val2
1    x     y  
2    x     z
3    z     z
4    x     y
4    x     z

您能否建议一种替代方法来实现结果而不是使用self join

2 个答案:

答案 0 :(得分:2)

select key1,
       max(case when key2 = 'val1' then value end) as val1
       max(case when key2 = 'val2' then value end) as val2
from MyTable
group by key1

答案 1 :(得分:1)

如果您显示的每个val2都有多个key1值,那么您需要做更多的工作,这是一个简单的支点。键(或组合)不是唯一的似乎很奇怪,如果你可以为两个 key2值设置多个值,或者只是{{1},那么它就不是完全清楚的。 }} ...

这假设您每个val2只能有一个val1,这可能不是一个有效的假设,但您的示例数据并非如此显示:

key1

模仿另一个CTE中的样本数据:

with cte as (
  select key1, key2, value,
    row_number() over (partition by key1, key2 order by key2) as key2_rn
  from mytable
)
select distinct key1,
  max(case when key2 = 'val1' then value end) over (partition by key1) as val1,
  max(case when key2 = 'val2' then value end) over (partition by key1, key2_rn) as val2
from cte;

给出:

with mytable (key1, key2, value) as (
  select 1, 'val1', 'x' from dual
  union all select 1, 'val2', 'y' from dual
  union all select 2, 'val1', 'x' from dual
  union all select 2, 'val2', 'z' from dual
  union all select 3, 'val2', 'z' from dual
  union all select 4, 'val1', 'x' from dual
  union all select 4, 'val2', 'y' from dual
  union all select 4, 'val2', 'z' from dual
),
cte as (
  select key1, key2, value,
    row_number() over (partition by key1, key2 order by key2) as key2_rn
  from mytable
)
select distinct key1,
  max(case when key2 = 'val1' then value end) over (partition by key1) as val1,
  max(case when key2 = 'val2' then value end) over (partition by key1, key2_rn) as val2
from cte
order by 1, 2, 3;

问题中的示例输出显示 KEY1 VAL1 VAL2 ---------- ---- ---- 1 x y 2 x z 3 z 4 x y 4 x z 的{​​{1}}列为key1=3,但您的数据没有。{1}}。如果您将其默认为val1值,那么这也是可以实现的,但会使其变得更加混乱。

您可以通过实际的枢轴操作(从11g开始)获得相同的结果:

'z'

这些还假设有val2个固定值;如果那个超过两个,那么这可以延长(我会轻易说,但这取决于你允许多次使用哪些键!)。如果没有固定的已知列表,并且您不知道最终会有多少列,那么除了现有的复杂情况之外,您还必须使用动态SQL。