分组创建垂直合并

时间:2014-09-08 22:41:17

标签: sql oracle pivot coalesce

我有这个问题。

select transaction, bbk, sbk, obk, ibk
from
(
  select 
    transaction, 
    case when "'BBK'" = 1 then country end bbk,
    case when "'SBK'" = 1 then country end sbk,
    case when "'OBK'" = 1 then country end obk,
    case when "'IBK'" = 1 then country end ibk  
  from (
    select 
    regexp_substr("col_a", '[^~]+', 1, 1) as transaction,
    regexp_substr("col_a", '[^~]+', 1, 2) as code,
    regexp_substr("col_a", '[^~]+', 1, 3) as country
    from Table1 t)
  pivot 
  ( 
    --case when count(code) = 1 then 
    count(code)
    for code in ('BBK','SBK','OBK','IBK')
  )  
)
group by transaction, bbk, sbk, obk, ibk
order by transaction

结果,如this fiddle

中所示
00004719    US  US  (null)  (null)
00004719    (null)  (null)  GB  (null)
00004719    (null)  (null)  (null)  DE

每笔交易显示多行。我想改变查询,以便每个事务只发生一行。

基本上垂直合并其他记录中的空值以实现:

00004719    US  US  GB  DE

怎么可能这样做?

2 个答案:

答案 0 :(得分:2)

您可以从查询结果开始,再次在事务列上分组:

with x as (
select transaction, bbk, sbk, obk, ibk
from
(
      select 
        transaction, 
        case when "'BBK'" = 1 then country end bbk,
        case when "'SBK'" = 1 then country end sbk,
        case when "'OBK'" = 1 then country end obk,
        case when "'IBK'" = 1 then country end ibk  
      from (
        select 
        regexp_substr("col_a", '[^~]+', 1, 1) as transaction,
        regexp_substr("col_a", '[^~]+', 1, 2) as code,
        regexp_substr("col_a", '[^~]+', 1, 3) as country
        from Table1 t)
      pivot 
      ( 
        --case when count(code) = 1 then 
        count(code)
        for code in ('BBK','SBK','OBK','IBK')
      )  
  )
group by transaction, bbk, sbk, obk, ibk
) select
transaction, max(bbk), max(sbk), max(obk), max(ibk)
from x
group by transaction
order by transaction;

Example SQLFiddle

编辑:

或等效地,只是在原始查询中按事务分组:

select 
  transaction, 
  max(case when "'BBK'" = 1 then country end) bbk,
  max(case when "'SBK'" = 1 then country end) sbk,
  max(case when "'OBK'" = 1 then country end) obk,
  max(case when "'IBK'" = 1 then country end) ibk  
from (
  select 
  regexp_substr("col_a", '[^~]+', 1, 1) as transaction,
  regexp_substr("col_a", '[^~]+', 1, 2) as code,
  regexp_substr("col_a", '[^~]+', 1, 3) as country
  from Table1 t)
pivot ( 
  count(code)
  for code in ('BBK','SBK','OBK','IBK')
)  
group by 
  transaction
order by 
  transaction;

Example SQLFiddle

答案 1 :(得分:2)

这正是pivot的用途:

select 
  transaction, 
  "'BBK'",
  "'SBK'",
  "'OBK'",
  "'IBK'"
from (
  select 
  regexp_substr("col_a", '[^~]+', 1, 1) as transaction,
  regexp_substr("col_a", '[^~]+', 1, 2) as code,
  regexp_substr("col_a", '[^~]+', 1, 3) as country
  from Table1 t)
pivot 
( 
  MAX(country) for code in ('BBK','SBK','OBK','IBK')
);