简体   繁体   中英

Oracle SQL Transpose rows into columns

I have the below data result set.

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

I would like to transpose these rows using columns LANG_ID , PROJ_DESC , COST_TYPE and VALUE .

I am trying to achieve the below result:

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

Any help on this would be highly appreciated.

Thanks.

One method uses conditional aggregation:

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;

Note: You are storing both numbers and strings in the VALUE column. This can prove tricky, when you want to treat the values as their native types.

Solution using PIVOT (available since Oracle 11.1). This adds the total_cost column, and explicitly converts the costs to numbers.

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
                                    )
      )
;

Output :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM