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.