Original table
+------------+---------+-------+-------------+--------+
| CampaignID | Medium | Month | Impressions | Clicks |
+------------+---------+-------+-------------+--------+
| A | Google | Jan | 15 | 2 |
| B | Google | Jan | 12 | 1 |
| A | YouTube | Jan | 11 | 2 |
| B | YouTube | Jan | 12 | 4 |
| A | Google | Feb | 15 | 3 |
| B | Google | Feb | 13 | 4 |
| A | YouTube | Feb | 12 | 2 |
| B | YouTube | Feb | 21 | 5 |
+------------+---------+-------+-------------+--------+
Expected result
+-----------+--------------------+---------------+---------------------+----------------+
| CampainID | Google Impressions | Google Clicks | YouTube Impressions | YouTube Clicks |
+-----------+--------------------+---------------+---------------------+----------------+
| A | 30 | 5 | 23 | 4 |
| B | 25 | 4 | 3 | 39 |
+-----------+--------------------+---------------+---------------------+----------------+
The number of values in the medium need to be generated at run time. This means that the number of columns in the query result are dynamic dependent on the data. What would be the most elegant solution in PostgreSQL?