Oracle SQL将行转置为列

时间:2016-08-23 08:18:14

标签: sql oracle pivot

我有以下数据结果集。

REQUEST_ID ATTRIBUTE_TYPE VENDOR LANG_ID  PROJ_DESC        COST_TYPE   VALUE
         1 DOCUMENT       JLK    1188     SAMPLE PROJECT1  USAGE_COST  500
         1 DOCUMENT       JLK    1188     SAMPLE PROJECT1  EXP_COST    350
         1 DOCUMENT       JLK    1188     SAMPLE PROJECT1  COMMENTS    OK
         1 DOCUMENT       JLK    1194     SAMPLE PROJECT1  USAGE_COST  400
         1 DOCUMENT       JLK    1194     SAMPLE PROJECT1  EXP_COST    575
         1 DOCUMENT       JLK    1194     SAMPLE PROJECT1  COMMENTS    DONE
         1 DOCUMENT       JLK    1188     SAMPLE PROJECT2  USAGE_COST  100
         1 DOCUMENT       JLK    1188     SAMPLE PROJECT2  EXP_COST    200
         1 DOCUMENT       JLK    1188     SAMPLE PROJECT2  COMMENTS    ACCEPTED
         1 DOCUMENT       JLK    1194     SAMPLE PROJECT2  USAGE_COST  300
         1 DOCUMENT       JLK    1194     SAMPLE PROJECT2  EXP_COST    400
         1 DOCUMENT       JLK    1194     SAMPLE PROJECT2  COMMENTS    GOOD

我想使用LANG_IDPROJ_DESCCOST_TYPEVALUE列来转置这些行。

我正在努力实现以下结果:

REQUEST_ID ATTRIBUTE_TYPE VENDOR LANG_ID PROJ_DESC       USAGE_COST EXP_COST TOTAL_COST COMMENTS
         1 DOCUMENT       JLK    1188    SAMPLE PROJECT1        500      350        850 OK
         1 DOCUMENT       JLK    1194    SAMPLE PROJECT1        400      575        975 DONE
         1 DOCUMENT       JLK    1188    SAMPLE PROJECT2        100      200        300 ACCEPTED
         1 DOCUMENT       JLK    1194    SAMPLE PROJECT2        300      400        700 GOOD

对此的任何帮助都将受到高度赞赏。

感谢。

2 个答案:

答案 0 :(得分:0)

一种方法使用条件聚合:

select REQUEST_ID, ATTRIBUTE_TYPE, VENDOR, LANG_ID, PROJ_DESC,
       max(case when COST_TYPE = 'USAGE_COST' then value end) as usage_cost,
       max(case when EXP_TYPE = 'EXP_COST' then value end) as exp_cost,
       max(case when COST_TYPE = 'COMMENTS' then value end) as comments
from t
group by REQUEST_ID, ATTRIBUTE_TYPE, VENDOR, LANG_ID, PROJ_DESC;

注意:您在VALUE列中存储了数字和字符串。当您希望将值视为其本机类型时,这可能会非常棘手。

答案 1 :(得分:0)

使用PIVOT的解决方案(自Oracle 11.1起可用)。这会添加total_cost列,并明确将费用转换为数字。

with
     input_data( REQUEST_ID, ATTRIBUTE_TYPE, VENDOR, LANG_ID, PROJ_DESC, COST_TYPE, VALUE ) as (
     select 1, 'DOCUMENT', 'JLK', 1188, 'SAMPLE PROJECT1', 'USAGE_COST', '500'      from dual union all
     select 1, 'DOCUMENT', 'JLK', 1188, 'SAMPLE PROJECT1', 'EXP_COST'  , '350'      from dual union all
     select 1, 'DOCUMENT', 'JLK', 1188, 'SAMPLE PROJECT1', 'COMMENTS'  , 'OK'       from dual union all
     select 1, 'DOCUMENT', 'JLK', 1194, 'SAMPLE PROJECT1', 'USAGE_COST', '400'      from dual union all
     select 1, 'DOCUMENT', 'JLK', 1194, 'SAMPLE PROJECT1', 'EXP_COST'  , '575'      from dual union all
     select 1, 'DOCUMENT', 'JLK', 1194, 'SAMPLE PROJECT1', 'COMMENTS'  , 'DONE'     from dual union all
     select 1, 'DOCUMENT', 'JLK', 1188, 'SAMPLE PROJECT2', 'USAGE_COST', '100'      from dual union all
     select 1, 'DOCUMENT', 'JLK', 1188, 'SAMPLE PROJECT2', 'EXP_COST'  , '200'      from dual union all
     select 1, 'DOCUMENT', 'JLK', 1188, 'SAMPLE PROJECT2', 'COMMENTS'  , 'ACCEPTED' from dual union all
     select 1, 'DOCUMENT', 'JLK', 1194, 'SAMPLE PROJECT2', 'USAGE_COST', '300'      from dual union all
     select 1, 'DOCUMENT', 'JLK', 1194, 'SAMPLE PROJECT2', 'EXP_COST'  , '400'      from dual union all
     select 1, 'DOCUMENT', 'JLK', 1194, 'SAMPLE PROJECT2', 'COMMENTS'  , 'GOOD'     from dual
     )
select request_id, attribute_type, vendor, lang_id, proj_desc,
       to_number(usage_cost) as usage_cost, to_number(exp_cost) as exp_cost,
       to_number(usage_cost) + to_number(exp_cost) as total_cost, comments
from   input_data
pivot ( max(value) for cost_type in ( 'USAGE_COST' as usage_cost,
                                      'EXP_COST'   as exp_cost  ,
                                      'COMMENTS'   as comments
                                    )
      )
;

<强>输出

REQUEST_ID ATTRIBUT VEN LANG_ID PROJ_DESC       USAGE_COST   EXP_COST TOTAL_COST COMMENTS
---------- -------- --- ------- --------------- ---------- ---------- ---------- --------
         1 DOCUMENT JLK    1194 SAMPLE PROJECT2        300        400        700 GOOD
         1 DOCUMENT JLK    1194 SAMPLE PROJECT1        400        575        975 DONE
         1 DOCUMENT JLK    1188 SAMPLE PROJECT1        500        350        850 OK
         1 DOCUMENT JLK    1188 SAMPLE PROJECT2        100        200        300 ACCEPTED