PostgreSQL Group By A,但仍拉B字段

时间:2013-11-24 14:19:00

标签: sql postgresql group-by pivot

我的表看起来像这样:

rpt_date   | shipping_id | total_usage 
--------------------------------------
2013-11-01 | 1           | 10
2013-11-01 | 2           | 2
2013-11-01 | 3           | 5
2013-11-02 | 1           | 15
2013-11-02 | 4           | 1
2013-11-03 | 1           | 20
2013-11-03 | 2           | 3

我想使用单个查询来获得如下结果:

rpt_date   | 1 (shipping _id) | 2 (shipping_id) | 3 (shipping_id) | 4 (shipping_id)
-----------------------------------------------------------------------------------
2013-11-01 | 10 (total_usage) | 2               | 5               | 0
2013-11-02 | 15               | 0               | 0               | 1
2013-11-03 | 20               | 3               | 0               | 0

我该如何查询?我试图像这样查询

SELECT 
  rpt_date,
  CASE WHEN shipping_id = 1 THEN total_usage ELSE 0 END AS a,
  CASE WHEN shipping_id = 2 THEN total_usage ELSE 0 END AS b,
  CASE WHEN shipping_id = 3 THEN total_usage ELSE 0 END AS c,
  CASE WHEN shipping_id = 4 THEN total_usage ELSE 0 END AS d
FROM 
  Table A
WHERE 
  DATE(rpt_date) BETWEEN '2013-11-01' AND '2013-11-03' 
GROUP BY 
  rpt_date 
ORDER BY 
  rpt_date

以上查询gimme错误,shipping_idtotal_usage必须是GROUP BY的一部分。我的查询有什么问题?

2 个答案:

答案 0 :(得分:2)

尝试使用SUM:

SELECT 
  rpt_date,
  SUM(CASE WHEN shipping_id = 1 THEN total_usage ELSE 0 END) AS a,
  SUM(CASE WHEN shipping_id = 2 THEN total_usage ELSE 0 END) AS b,
  SUM(CASE WHEN shipping_id = 3 THEN total_usage ELSE 0 END) AS c,
  SUM(CASE WHEN shipping_id = 4 THEN total_usage ELSE 0 END) AS d
FROM TableA
WHERE DATE(rpt_date) BETWEEN '2013-11-01' AND '2013-11-03' 
GROUP BY rpt_date 
ORDER BY rpt_date

sqlfiddle demo

您正在按rpt_date进行分组,但没有告诉其他列会发生什么。这样您就可以获得这些日期的total_usage的SUM。如果您只有一条记录,则对于每个日期和每个shipping_id,它将仅返回该值。

答案 1 :(得分:0)

您的查询已结束。获得此数据结果的一种方法是:

SELECT 
  rpt_date,
  MAX(CASE WHEN shipping_id = 1 THEN total_usage ELSE 0 END) AS a,
  MAX(CASE WHEN shipping_id = 2 THEN total_usage ELSE 0 END) AS b,
  MAX(CASE WHEN shipping_id = 3 THEN total_usage ELSE 0 END) AS c,
  MAX(CASE WHEN shipping_id = 4 THEN total_usage ELSE 0 END) AS d
FROM 
  Table A
WHERE 
  rpt_date BETWEEN '2013-11-01' AND '2013-11-03' 
GROUP BY 
  rpt_date 
ORDER BY 
  rpt_date ;