Как объединить ячейки из одной таблицы, но из разных строк? - PullRequest
0 голосов
/ 19 февраля 2019

У меня следующая проблема.У меня есть несколько строк в моей таблице, которые почти одинаковы, и мне нужно несколько ячеек для конкремента с ячейками выше.Моя текущая инструкция 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 работают как категории, например, первая запись выглядитlike (0 = пусто / null): «1-0-0-0-0-0-0-0 AKTIVA», вторая запись выглядит как «1-1-0-0-0-0-0 BTIVA».SO BTIVA - это подкатегория от AKTIVA.Есть несколько строк, которые содержат 1 или 2 в BLTUGP.Если это так, я хотел бы объединить запись 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 голосов
/ 21 февраля 2019

Мне удалось найти решение

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;
0 голосов
/ 19 февраля 2019

Вы хотите, чтобы для каждой комбинации других значений столбца текст, связанный с нулевым 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                                                                              

Или, если вы хотите видеть только строки с нулевым индексом, когда для этой комбинации нет других, вы можете считать ненулевые записидля каждой комбинации, и исключайте пустые значения только в том случае, если существует ненулевое значение (подразумевается, что нулевое значение было добавлено и не нужно само по себе - если это действительно правило, которое вам нужно):

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                                                                              

До сих пор не совсем ясно, что вы хотите увидеть ...

0 голосов
/ 19 февраля 2019

Самостоятельно присоединитесь к вашему текущему результату, как в этом примере:

-- 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
0 голосов
/ 19 февраля 2019

Вы можете использовать LISTAGG (начиная с Oracle 11.2), чтобы сделать это.Вот ссылка о том, как это сделать.

Если вы работаете на более низкой версии Oracle, вы можете использовать WM_CONCAT, если она поддерживается.

...