如何在Oracle中将多行合并为单行

mad*_*mad 4 sql oracle

我正在寻找将多行合并为单行的想法

可以说我有这样的表:

ID |  A  |  B  |  C  |  D  |
____________________________
 1 |  x  |  y  |null |  z  |
 2 |null |  z  |null |  x  |
 3 | p   |  w  | a   |null |
 4 | o   |null | k   |null |
Run Code Online (Sandbox Code Playgroud)

现在我需要将具有较低ID的所有行的更改应用于每一行.第一行是一个基础所以它应该看起来:

1 |  x  |  y  |null |  z  |
Run Code Online (Sandbox Code Playgroud)

现在,对于第二行,我需要从第一行开始并从第二行应用更改(如果列不为空).第二行应该是这样的:

2 |  x  |  z  |null |  x  |
Run Code Online (Sandbox Code Playgroud)

第三行 - 从第一行开始,从第二行和第三行应用更改:

3 |  p  |  w  |  a  |  x  |
Run Code Online (Sandbox Code Playgroud)

第四行 - 取第一行,应用第二行,第三行和第四行:

4 |  o  |  w  |  k  |  x  | 
Run Code Online (Sandbox Code Playgroud)

所以输出应该是这样的:

1 |  x  |  y  |null |  z  |
2 |  x  |  z  |null |  x  |
3 |  p  |  w  |  a  |  x  |
4 |  o  |  w  |  k  |  x  | 
Run Code Online (Sandbox Code Playgroud)

是否有可用于此的Oracle功能?

Ale*_*ole 6

您可以使用last_value()功能,使用以下ignore nulls选项:

last_value(a) ignore nulls over (order by id)
Run Code Online (Sandbox Code Playgroud)

将为您提供a列中看到的最后一个非空值,直到当前ID(使用默认窗口); 所以你可以为你想要"合并"的每一列重复这个:

select id,
  last_value(a) ignore nulls over (order by id) as a,
  last_value(b) ignore nulls over (order by id) as b,
  last_value(c) ignore nulls over (order by id) as c,
  last_value(d) ignore nulls over (order by id) as d
from your_table
order by id;
Run Code Online (Sandbox Code Playgroud)

将您的样本数据作为CTE:

with your_table (id,  a,  b,  c,  d) as (
            select 1, 'x', 'y', null, 'z' from dual
  union all select 2, null, 'z', null,'x' from dual
  union all select 3, 'p', 'w', 'a', null from dual
  union all select 4, 'o', null, 'k', null from dual
)
select id,
  last_value(a) ignore nulls over (order by id) as a,
  last_value(b) ignore nulls over (order by id) as b,
  last_value(c) ignore nulls over (order by id) as c,
  last_value(d) ignore nulls over (order by id) as d
from your_table
order by id;

        ID A B C D
---------- - - - -
         1 x y   z
         2 x z   x
         3 p w a x
         4 o w k x
Run Code Online (Sandbox Code Playgroud)


kro*_*lko 5

使用层次查询:

CREATE TABLE abcd(
  id int,
   A  varchar2(10),
   B varchar2(10),  
   C varchar2(10),  D varchar2(10)
);

insert all
  into abcd values(1,'x','y',null,'z')
  into abcd values(2,null,'z',null,'x')
  into abcd values(3,'p','w','a',null)
  into abcd values(4,'o',null,'k',null)
select 1 from dual;

commit;
Run Code Online (Sandbox Code Playgroud)
WITH qq(id, a,b,c,d) AS(
   SELECT id, a,b,c,d FROM abcd WHERE id = 1
   UNION ALL
   SELECT x.id, 
          coalesce( x.a, qq.a ),
          coalesce( x.b, qq.b ),
          coalesce( x.c, qq.c ),
          coalesce( x.d, qq.d )
   FROM qq
   JOIN abcd x ON x.id = qq.id + 1
)
SELECT * FROM qq;

       ID A          B          C          D         
---------- ---------- ---------- ---------- ----------
         1 x          y                     z         
         2 x          z                     x         
         3 p          w          a          x         
         4 o          w          k          x         
Run Code Online (Sandbox Code Playgroud)