根据一列值将多行合并为单行

时间:2020-03-20 07:41:17

标签: oracle oracle11g grouping

我想根据称为类型的一列将多行结果合并为单行。

例如,假设我的查询结果如下。

├── Dockerfile
├── Laboratory.API
|  ├── Application
|  ├── appsettings.json
|  ├── Controllers
|  ├── healthcheck-ui.css
|  ├── Laboratory.API.csproj
|  ├── Program.cs
|  ├── Properties
|  ├── Startup.cs
├── Laboratory.Domain
|  ├── AggregateModel
|  ├── Exceptions
|  ├── Laboratory.Domain.csproj
|  └── SeedWork
├── Laboratory.Infrastructure
|  ├── EntityConfigurations
|  ├── Laboratory.Infrastructure.csproj
|  ├── Migrations
|  ├── LaboratoryContext.cs
|  └── Repositories

我想要的实际结果如下表

seqnum  type    name
456     SH    Google2
456     CN    transwork
123     SH    partyshipper
123     CN    consignee

基本上,我想得到类型为CN的收货人名称之类的结果,而类型为SH时的托运人名称不是两者的话,那么我可以像其他方一样添加具有名称的额外列。 我可以获得结果并迭代结果集和对象的设置值。但是我认为如果只在查询中获取格式化结果会更好。可以帮上忙。 感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

通常这样会有所帮助;第1-7行代表您的样本数据。您需要的代码从第8行开始。

SQL> with test (seqnum, type, name) as
  2    (select 456, 'SH', 'Google2'      from dual union all
  3     select 456, 'CN', 'transwork'    from dual union all
  4     select 123, 'SH', 'partyshipper' from dual union all
  5     select 123, 'CN', 'consignee'    from dual union all
  6     select 999, 'XX', 'littlefoot'   from dual
  7    )
  8  select seqnum,
  9    max(case when type = 'CN' then name end) consigneename,
 10    max(case when type = 'SH' then name end) shipppername,
 11    max(case when type not in ('CN', 'SH') then name end) otherparty
 12  from test
 13  group by seqnum;

    SEQNUM CONSIGNEENAM SHIPPPERNAME OTHERPARTY
---------- ------------ ------------ ------------
       123 consignee    partyshipper
       999                           littlefoot
       456 transwork    Google2

SQL>

答案 1 :(得分:1)

从@Littlefoot借用查询。您也可以使用PIVOT获得预期的结果。

    with test (seqnum, type, name) as
      (select 456, 'SH', 'Google2'      from dual union all
       select 456, 'CN', 'transwork'    from dual union all
       select 123, 'SH', 'partyshipper' from dual union all
       select 123, 'CN', 'consignee'    from dual union all
       select 999, 'OT', 'littlefoot'   from dual
      )
select * from test
pivot (
  min(name) for type in 
      (        
        'SH' shippingname
      , 'CN' consigneename 
      , 'OT' someother
      )
)
;


    SEQNUM SHIPPINGNAME CONSIGNEENAM SOMEOTHER   
---------- ------------ ------------ ------------
       999                           littlefoot  
       456 Google2      transwork                
       123 partyshipper consignee                

答案 2 :(得分:0)

我将自行联接表并在联接的每一侧过滤不同的type

SELECT          COALESCE(c.seqnum, s.seqnum) AS seqnum,
                COALESCE(c.name, 'other') AS consigneename,
                COALESCE(s.name, 'other') AS shippername
FROM            (SELECT * 
                 FROM   mytable
                 WHERE  type = 'CN') c
FULL OUTER JOIN (SELECT *
                 FROM   mytable
                 WHERE  type = 'SN') s ON c.seqnum = s.seqnum