如何编写可以提供以下结果的SQL?

时间:2016-09-16 08:46:40

标签: sql postgresql pivot crosstab

原始表

+------------+---------+-------+-------------+--------+
| 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 |
+------------+---------+-------+-------------+--------+

预期结果

+-----------+--------------------+---------------+---------------------+----------------+
| CampainID | Google Impressions | Google Clicks | YouTube Impressions | YouTube Clicks |
+-----------+--------------------+---------------+---------------------+----------------+
| A         |                 30 |             5 |                  23 |              4 |
| B         |                 25 |             4 |                   3 |             39 |
+-----------+--------------------+---------------+---------------------+----------------+

需要在运行时生成介质中的值数。这意味着查询结果中的列数是动态,具体取决于数据。 PostgreSQL中最优雅的解决方案是什么?

1 个答案:

答案 0 :(得分:1)

您可以这样查询:

WITH Src AS
(
SELECT * FROM (VALUES
  ('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)) T(CampaignID, Medium, Month, Impressions, Clicks)
) --End sample data

SELECT CampaignID,
  SUM(CASE WHEN Medium='Google' THEN Impressions ELSE 0 END) "Google Impessions",
  SUM(CASE WHEN Medium='Google' THEN Clicks ELSE 0 END) "Google Clicks",
  SUM(CASE WHEN Medium='YouTube' THEN Impressions ELSE 0 END) "YouTube Impessions",
  SUM(CASE WHEN Medium='YouTube' THEN Clicks ELSE 0 END) "YouTube Clicks"
FROM Src
GROUP BY CampaignID