I have 2 mysql tables that i want to join, but i want the column ‘category’ results to be in a new column, not rows.
the first one looks something like this
table name = petshop.product |==========================| |product_id | product_name | |==========================| | 1 | Dog & Cat Toy| | 2 | Dog Food | |==========================|
and the second one looks like this
table name = petshop.category |============================| |category_id | category_name | |============================| | 1 |Dog | | 2 |Food | | 3 |Toy | | 4 |Cat | |============================|
and i have another table to store the relations that looks like this
table name = petshop.product_category ================================= |pc_id| product_id | category_id| |===============================| | 1 | 1 | 1 | | 2 | 1 | 3 | | 3 | 1 | 4 | | 4 | 2 | 1 | | 5 | 2 | 2 | |===============================|
how can i output a table where the result looks like this
|====================================================| |product_name| category1 | category2 | category3 | |====================================================| |Dog&Cat Toy | Dog | Toy | Cat | |Dog Food | Dog | Food | NULL | |====================================================|
I read about pivot but i can’t wrap my head around it (really new to mysql and coding in general to be honest). Thank you!
Advertisement
Answer
In MySQL 8.0, you can address this with joins, row_number()
to enumerate the categories per product, and conditional aggregation to pivot the resultset:
select product_name, max(case when rn = 1 then category_name end) category1, max(case when rn = 2 then category_name end) category2, max(case when rn = 3 then category_name end) category3 from ( select p.product_id, p.product_name, c.category_name, row_number() over(partition by p.product_id order by c.category_id) rn from product p inner join product_category pc on pc.product_id = p.product_id inner join category c on c.category_id = pc.category_id ) t group by product_id, product_name