如何连接来自相同 table 但不同行的单元格?

How to concat cells from same table but different row?

我有以下问题。 我的 table 中有几行几乎相同,我需要一些单元格与上面的单元格连接。 我当前的 Select 语句如下所示:

Select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp
      ,regexp_replace(regexp_replace(LISTAGG(bltxt,' '),'\s+',' '),'¯+','') AS Text 
from atdata.bip105
where bltspriso = 'DEAT'
group by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp
order by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp

输出看起来像这样

BLTGS1-6 像类别一样工作,例如第一个条目看起来像 (0 = empty/null): "1-0-0-0-0-0-0-0 AKTIVA" 第二个条目看起来像“1-1-0-0-0-0-0 BTIVA”。 SO BTIVA 是 AKTIVA 的子类别。 BLTUGP 中有些行包含 1 或 2。如果是这种情况,我想将 TEXT 条目连接到上面的第一行,其中不包含 BLTUGP 中的数字。所以关于文本,它应该看起来像,例如:

BLTUGP| TEXT
      | TOM
 1    | likes salat.
 2    | likes tomatoes.

此示例的输出应如下所示:

BLTUGP| TEXT
      | TOM
 1    | TOM likes salat.
 2    | TOM like tomatoes.

如您所见,带有 "erhaltene Anzahlungen auf Bestellung" 的行应如下所示:

2 - 1 - 12 - 01 - 007 - 01 - "erhaltene Anzahlungen auf Bestellung davon mit einer Restlaufzeit von bis zu einem Jahr" 

2 - 1 - 12 - 01 - 007 - 02 - "erhaltene Anzahlungen auf Bestellung davon mit einer Restlaufzeit von mehr als einem Jahr"

...但我还需要 bltugp 所在的所有行 empty/null。 附加信息!我无法 manipulate/change 来源 table。

提前致谢!

更新: 我试过了

with 

tbl_wougp as

  (Select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp ,regexp_replace(regexp_replace(LISTAGG(bltxt,' '),'\s+',' '),'¯+','') AS Text

    from atdata.bip105

    where bltspriso = 'DEAT' and bltugp=''

    group by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp),

tbl_wugp as

  (Select u.bltgs1, u.bltgs2, u.bltgs3, u.bltgs4, u.bltgs5, u.bltgs6, u.bltugp, concat(concat(trim(h.bltxt), ' '), trim(u.bltxt))  as Text from 

    (select * from atdata.bip105 where bltspriso = 'DEAT' and bltugp='') h right join

    (select * from atdata.bip105 where bltspriso = 'DEAT' and bltugp<>'') u

   on u.bltgs1=h.bltgs1 and u.bltgs2=h.bltgs2 and u.bltgs3=h.bltgs3 and u.bltgs4=h.bltgs4 and u.bltgs5=h.bltgs5 and u.bltgs6=u.bltgs6 

)

select * from tbl_wougp

union 

select * from tbl_wugp

order by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6;

几乎按预期工作,但有些行似乎翻了一番,我不知道为什么。

您可以使用 LISTAGG(从 Oracle 11.2 开始)执行此操作。这是关于如何执行此操作的 link

如果您 运行 使用的是较低版本的 Oracle,则可以使用 WM_CONCAT(如果它受支持)。

对于其他列值的每个组合,您似乎希望将与空 bltugp 关联的文本添加到与所有非空值关联的文本之前。

一种方法是使用串联和分析函数来查找要添加的基于空的文本:

max(case when bltugp is null then bltxt end)
        over (partition by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz)
      || bltxt

这会给你三行:

    BLTGS1     BLTGS2     BLTGS3 BL BLT BLTGS6 BL TEXT                                                                                                    
---------- ---------- ---------- -- --- ------ -- --------------------------------------------------------------------------------------------------------
         2          1         12 01 007        01 erhaltene Anzahlungen auf Bestellungdavon mit einer Restlaufzeit von bis zu einem Jahr                  
         2          1         12 01 007        02 erhaltene Anzahlungen auf Bestellungdavon mit einer Restlaufzeit von mehr als einem Jahr                
         2          1         12 01 007           erhaltene Anzahlungen auf Bestellungerhaltene Anzahlungen auf Bestellung                                

...然后丢弃你不想要的那个。作为示例,这些行和其他一些可能有趣的行作为示例数据:

-- CTE for dummy data
with bip105 (bltspriso, blttkz, bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp, bltxt) as (
  select 'DEAT', 42, 2, 1, 12, '01', '006', null, '02', 'davon mit einer Restlaufzeit von mehr als einem Jahr' from dual
  union all
  select 'DEAT', 42, 2, 1, 12, '01', '007', null, null, 'erhaltene Anzahlungen auf Bestellung' from dual
  union all
  select 'DEAT', 42, 2, 1, 12, '01', '007', null, '01', 'davon mit einer Restlaufzeit von bis zu einem Jahr' from dual
  union all
  select 'DEAT', 42, 2, 1, 12, '01', '007', null, '02', 'davon mit einer Restlaufzeit von mehr als einem Jahr' from dual
  union all
  select 'DEAT', 42, 2, 1, 12, '01', '021', null, null, 'sonstige Verbindlichkeiten' from dual
)
-- actual query
select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp, text
from (
  select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp
    , max(case when bltugp is null then bltxt end)
        over (partition by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz)
      || bltxt as text
  from bip105
  where bltspriso = 'DEAT'
)
where bltugp is not null
order by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp;
    BLTGS1     BLTGS2     BLTGS3 BL BLT BLTGS6 BL TEXT                                                                                                    
---------- ---------- ---------- -- --- ------ -- --------------------------------------------------------------------------------------------------------
         2          1         12 01 006        02 davon mit einer Restlaufzeit von mehr als einem Jahr                                                    
         2          1         12 01 007        01 erhaltene Anzahlungen auf Bestellungdavon mit einer Restlaufzeit von bis zu einem Jahr                  
         2          1         12 01 007        02 erhaltene Anzahlungen auf Bestellungdavon mit einer Restlaufzeit von mehr als einem Jahr                

如果您还想显示所有基于空值的行,您可以删除过滤器,但还需要停止将该值添加到自身;可能更简单的方法,但这是使用另一种 case 表达式的方法:

select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp, text
from (
  select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp
    , max(case when bltugp is null then bltxt end)
        over (partition by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz)
      || case when bltugp is not null then bltxt end as text
  from bip105
  where bltspriso = 'DEAT'
)
order by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp

    BLTGS1     BLTGS2     BLTGS3 BL BLT BLTGS6 BL TEXT                                                                                                    
---------- ---------- ---------- -- --- ------ -- --------------------------------------------------------------------------------------------------------
         2          1         12 01 006        02 davon mit einer Restlaufzeit von mehr als einem Jahr                                                    
         2          1         12 01 007        01 erhaltene Anzahlungen auf Bestellungdavon mit einer Restlaufzeit von bis zu einem Jahr                  
         2          1         12 01 007        02 erhaltene Anzahlungen auf Bestellungdavon mit einer Restlaufzeit von mehr als einem Jahr                
         2          1         12 01 007           erhaltene Anzahlungen auf Bestellung                                                                    
         2          1         12 01 021           sonstige Verbindlichkeiten                                                                              

或者,如果您只想在该组合没有其他行时查看基于空值的行,则可以计算每个组合的非空条目,并且仅在存在任何非空值时排除空值(暗示 null 已经被添加到前面并且不需要它自己 - 如果这确实是你需要的规则):

select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp, text
from (
  select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp
    , max(case when bltugp is null then bltxt end)
        over (partition by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz)
      || case when bltugp is not null then bltxt end as text
    , count(bltugp) over (partition by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz)
      as non_null_count
  from bip105
  where bltspriso = 'DEAT'
)
where non_null_count = 0 or bltugp is not null
order by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp;

    BLTGS1     BLTGS2     BLTGS3 BL BLT BLTGS6 BL TEXT                                                                                                    
---------- ---------- ---------- -- --- ------ -- --------------------------------------------------------------------------------------------------------
         2          1         12 01 006        02 davon mit einer Restlaufzeit von mehr als einem Jahr                                                    
         2          1         12 01 007        01 erhaltene Anzahlungen auf Bestellungdavon mit einer Restlaufzeit von bis zu einem Jahr                  
         2          1         12 01 007        02 erhaltene Anzahlungen auf Bestellungdavon mit einer Restlaufzeit von mehr als einem Jahr                
         2          1         12 01 021           sonstige Verbindlichkeiten                                                                              

还不是很清楚你想看什么...

自行加入您当前的结果,如本例所示:

-- sample data
with your_query(bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltugp, text) as (
  select 2, 1, 12, '01', '007', null, 'Tom wants to'  from dual union all
  select 2, 1, 12, '01', '007', '01', 'sleep'         from dual union all
  select 2, 1, 12, '01', '007', '02', 'play'          from dual union all
  select 2, 1, 12, '01', '008', null, 'Mark is'       from dual union all
  select 2, 1, 12, '01', '008', '01', 'cheerful'      from dual union all
  select 2, 1, 12, '01', '008', '02', 'sad'           from dual )
-- end of sample data

select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, b.bltugp,
       a.text||' '||b.text text
  from your_query a 
  join your_query b using (bltgs1, bltgs2, bltgs3, bltgs4, bltgs5)
  where (a.bltugp is null and b.bltugp = '01') 
     or (a.bltugp is null and b.bltugp = '02')
  order by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, b.bltugp

...我们得到:

BLTGS1     BLTGS2     BLTGS3 BLTGS4 BLTGS5 BLTUGP TEXT
------ ---------- ---------- ------ ------ ------ -------------------------
     2          1         12 01     007    01     Tom wants to sleep
     2          1         12 01     007    02     Tom wants to play
     2          1         12 01     008    01     Mark is cheerful
     2          1         12 01     008    02     Mark is sad

我设法找到了解决方案

with 

tbl_wougp as
(Select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp ,regexp_replace(regexp_replace(LISTAGG(bltxt,' '),'\s+',' '),'¯+','') AS Text
from atdata.bip105
where bltspriso = 'DEAT' and bltugp=''
group by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp),

tbl_wugp as
(Select bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp ,regexp_replace(regexp_replace(LISTAGG(bltxt,' '),'\s+',' '),'¯+','') AS Text
from atdata.bip105
where bltspriso = 'DEAT' and bltugp<>''
group by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, blttkz, bltugp)

select * from tbl_wougp
union
select u.bltgs1, u.bltgs2, u.bltgs3, u.bltgs4, u.bltgs5, u.bltgs6, u.bltugp, concat(concat(trim(h.text), ' '), trim(u.text)) as Text
from tbl_wugp u left join tbl_wougp h
on u.bltgs1=h.bltgs1 and u.bltgs2=h.bltgs2 and u.bltgs3=h.bltgs3 and u.bltgs4=h.bltgs4 and u.bltgs5=h.bltgs5 and u.bltgs6=h.bltgs6 
order by bltgs1, bltgs2, bltgs3, bltgs4, bltgs5, bltgs6, bltugp, text;