Oracle преобразовать тип данных столбца в несколько столбцов - PullRequest
0 голосов
/ 11 июля 2020

Привет, у меня есть таблица, содержащая транзакции между несколькими сторонами, как показано ниже:

DATE|FROM|TO|QTY|TYPE
01012020, A, B, 100, LEND
01042020, A, B, 200, LEND
01092020, A, B, 300, LEND
02012020, A, C, 50, LEND
02062020, A, C, 300, LEND
02042020, C, A, 50, REPAY
03042020, D, A, 200, LEND
04062020, A, D, 200, REPAY

Как преобразовать данные таблицы в следующую форму?

FROM|TO|LEND|REPAY
A, B, 600, 0
A, C, 350, 50
D, A, 200, 200

Большое спасибо!

Ответы [ 4 ]

2 голосов
/ 11 июля 2020
with
  sample_data(tx_date, p_from, p_to, qty, tx_type) as (
    select to_date('01012020','ddmmyyyy'), 'A', 'B', 100, 'LEND'  from dual union all
    select to_date('01042020','ddmmyyyy'), 'A', 'B', 200, 'LEND'  from dual union all
    select to_date('01092020','ddmmyyyy'), 'A', 'B', 300, 'LEND'  from dual union all
    select to_date('02012020','ddmmyyyy'), 'A', 'C',  50, 'LEND'  from dual union all
    select to_date('02062020','ddmmyyyy'), 'A', 'C', 300, 'LEND'  from dual union all
    select to_date('02042020','ddmmyyyy'), 'C', 'A',  50, 'REPAY' from dual union all
    select to_date('03042020','ddmmyyyy'), 'D', 'A', 200, 'LEND'  from dual union all
    select to_date('04062020','ddmmyyyy'), 'A', 'D', 200, 'REPAY' from dual
  )
select p_from, p_to, nvl(lend, 0) as lend, nvl(repay, 0) as repay
from   (select case tx_type when 'LEND' then p_from else p_to      end as p_from
             , case tx_type when 'LEND' then p_to   else p_from end as p_to
             , qty, tx_type
        from   sample_data
       )
pivot  (sum(qty) for tx_type in ('LEND' as lend, 'REPAY' as repay))
order  by p_from, p_to   --  or whatever you need to order by
;
P_FROM P_TO         LEND      REPAY
------ ------ ---------- ----------
A      B             600          0
A      C             350         50
D      A             200        200

Обратите внимание, что FROM - зарезервированное ключевое слово, как и DATE - я использовал несколько другие имена столбцов, поэтому они не содержат sh с ключевыми словами SQL.

2 голосов
/ 11 июля 2020

С агрегацией для каждого из случаев 'LEND' и 'REPAY' с последующим присоединением:

SELECT t1."FROM", t1."TO", t1.QTY "LEND", COALESCE(t2."QTY", 0) "REPAY"
FROM (
  SELECT "FROM", "TO", SUM(QTY) QTY 
  FROM tablename 
  WHERE "TYPE" = 'LEND'
  GROUP BY "FROM", "TO"
) t1 LEFT JOIN (
  SELECT "FROM", "TO", SUM(QTY) QTY 
  FROM tablename 
  WHERE "TYPE" = 'REPAY'
  GROUP BY "FROM", "TO"
) t2 ON t1."FROM" = t2."TO" AND t1."TO" = t2."FROM"
ORDER  BY t1."FROM", t1."TO"

См. Демонстрацию . Результатов:

> FROM | TO | LEND | REPAY
> :--- | :- | ---: | ----:
> A    | B  |  600 |     0
> A    | C  |  350 |    50
> D    | A  |  200 |   200
0 голосов
/ 11 июля 2020

Вы можете использовать union all и group by следующим образом:

SELECT from, to,
       Sum(case when type = 'LEND' then qty else 0 end) as lend,
       Sum(case when type = 'REPAY' then qty else 0 end) as repay 
  From
(Select date, from, to, qty, type from your_table where type = 'LEND'
Union all
Select date, to, from, qty, type from your_table where type = 'REPAY')
Group by from, to
0 голосов
/ 11 июля 2020

Я пробовал немного по-другому, используя те же DDL и DML, которые опубликовал @forpas, этот подход также работает для меня, пожалуйста, проверьте его с дополнительными данными.

select * from 
(select "FROM", "TO", CASE WHEN "TYPE" = 'LEND' then "QTY" end as LEND,
CASE WHEN ( "TYPE" = 'LEND' and lead("TYPE") over (order by "TYPE") <>'REPAY' )  then 0 else "QTY" end as REPAY 
from tablename 
)
where LEND is not null; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...