Reputation: 89
I have some data coming in from an external source that I need to pivot into the right columns. Problem is that the id and one more column are not repeated for all the rows. Example data:
Rownumber ID Type Category Value
1 100 1-Purchase Order Address Cedar Rd
2 City Beachwood
3 State Ohio
4 Zip 44122
5 300 1-Purchase Order Address Rockside Rd
6 City Independence
7 State Ohio
8 Zip 44131
9 200 1-Purchase Order Address Rockside Rd
10 City Independence
11 State Ohio
12 Zip 44131
Desired output is
Rownumber ID Type Address City State Zip
1 100 1-Purchase Order Cedar Rd Beachwood Ohio 44122
2 300 1-Purchase Order Rockside Rd Independence Ohio 44122
3 200 1-Purchase Order Rockside Rd Independence Ohio 44122
Please note the ID appears in random order, because of which this code did not work:
select row_number() over (order by min(id)) as rownumber,
new_id as id,
max(type) as type,
max(case when category = 'Address' then value end) as address,
max(case when category = 'City' then value end) as city,
max(case when category = 'State' then value end) as state,
max(case when category = 'Zip' then value end) as zip
from (select t.*,
coalesce(id, max(id) over (order by rownumber)) as new_id
from t
) t
group by new_id;
Upvotes: 3
Views: 44
Reputation: 1270191
You can easily fix this code because you don't really need the ids. You just need a way to define the groups. So, a cumulative count should do the same thing:
select row_number() over (order by min(rownumber)) as rownumber,
max(id) as id,
max(type) as type,
max(case when category = 'Address' then value end) as address,
max(case when category = 'City' then value end) as city,
max(case when category = 'State' then value end) as state,
max(case when category = 'Zip' then value end) as zip
from (select t.*,
count(id) over (order by rownumber) as grp
from t
) t
group by grp;
This assigns all NULL
values to the immediately preceding non-null id
grouping.
Here is a db<>fiddle.
Upvotes: 5