如何连接来自同一表但不同行的单元格?

时间:2019-02-19 14:56:31

标签: sql oracle select string-aggregation lead

我有以下问题。 我的表中有些行几乎是相同的,我需要一些单元格来与上面的单元格连接。 我当前的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

输出看起来像这样enter image description here

BLTGS1-6的工作方式类似于类别,例如,第一项看起来像(0 =空/空):“ 1-0-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为空/空的所有行。 附加信息!我无法操纵/更改源表。

谢谢!

更新: 我尝试过

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;

几乎可以按预期工作,但有些行似乎翻了一番,我也​​不是为什么。

4 个答案:

答案 0 :(得分:0)

您可以使用LISTAGG(从Oracle 11.2开始)执行此操作。这是link,有关操作方法。

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

答案 1 :(得分:0)

对于其他列值的每种组合,您似乎希望将与空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                                                                              

还不清楚您想看什么...

答案 2 :(得分:0)

自动加入当前结果,如以下示例所示:

-- 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

答案 3 :(得分:0)

我设法找到了解决方法

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;