1 sql oracle pivot denormalization
我正在尝试为新表准备数据,该表与现有表中的数据相同但是非规范化.我有一个简单的场景,但我的想法是以最有效的方式返回结果
它基于以下简化方案:
Table X | Table y
id | id Identifier Value
123 | 123 1 A
| 123 2 B
Run Code Online (Sandbox Code Playgroud)
与表XI中的其他字段一起需要我的查询返回:
123 A B
Run Code Online (Sandbox Code Playgroud)
我考虑过:
解决方案一
select
id,
(select Value...),
(select Value...)...
Run Code Online (Sandbox Code Playgroud)
解决方案二:
select id,
y1.Value,
y2.Value
from x, y y1, y y2...
Run Code Online (Sandbox Code Playgroud)
解决方案三:使用PL/SQL并迭代游标
解决方案四:将y提取到两个表identifyyer1和identifier2(可能使用触发器)并在查询中连接这些表
由于这个或那个原因,这些解决方案中的每一个都有一个主要的缺点,我确信一个词可以让我想起一个解决这个问题的概念
除非我失去了一些东西,你正试图转动数据.有几种方法可以做到这一点.
您可以使用聚合函数和CASE表达式:
select x.id,
max(case when y.identifier = 1 then y.value end) Value1,
max(case when y.identifier = 2 then y.value end) Value2
from tablex x
left join tabley y
on x.id = y.id
group by x.id
Run Code Online (Sandbox Code Playgroud)
根据您的Oracle版本,您可以使用以下PIVOT功能:
select id,
Value1,
Value2
from
(
select x.id, y.identifier, y.value
from tablex x
left join tabley y
on x.id = y.id
)
pivot
(
max(value)
for identifier in ('1' as Value1, '2' as Value2)
) piv
Run Code Online (Sandbox Code Playgroud)
您可以多次加入:
select x.id,
y1.value Value1,
y2.value Value2
from tablex x
left join tabley y1
on x.id = y1.id
and y1.identifier = 1
left join tabley y2
on x.id = y2.id
and y2.identifier = 2
Run Code Online (Sandbox Code Playgroud)
如果您正在寻找动态解决方案,那么您可以使用sys_refcursor创建一个过程:
CREATE OR REPLACE procedure dynamic_pivot(p_cursor in out sys_refcursor)
as
sql_query varchar2(8000) := 'select x.id ';
begin
for x in (select distinct identifier from tabley order by 1)
loop
sql_query := sql_query ||
' , max(case when y.identifier = '||x.identifier||' then y.value else null end) as Value'||x.identifier;
dbms_output.put_line(sql_query);
end loop;
sql_query := sql_query || ' from tablex x
left join tabley y
on x.id = y.id
group by x.id';
dbms_output.put_line(sql_query);
open p_cursor for sql_query;
end;
/
Run Code Online (Sandbox Code Playgroud)
这些解决方案为每个值提供单独列中的结果.如果您想将数据放在一个列中,那么您可以使用LISTAGG():
select x.id,
listagg(y.value, ' ') within group (order by y.id) as Value
from tablex x
left join tabley y
on x.id = y.id
group by x.id
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4027 次 |
| 最近记录: |