使用两列行数据在PostgreSQL中透视数据

时间:2015-08-11 13:25:33

标签: postgresql group-by

在PostgreSQL中,我有一个表country和一个表property。一个国家可以拥有很多房产。每个属性都有created_at。我需要计算按年和周分隔的每个国家/地区的属性。就像一个例子,我有一个国家的查询。

SELECT 
  EXTRACT(YEAR FROM created_at) AS yy, 
  EXTRACT(WEEK FROM created_at) AS week, 
  COUNT(id) AS country_1
FROM property 
WHERE id_country = 1
GROUP BY week, yy 
ORDER BY yy, week ASC

结果是这样的

yy  |week|country_1
---------------
2014|1   |5
2014|2   |1154
2014|3   |769
...

所以,我需要这样的结果

yy  |week|country_1|country_2|country_3
----------------------------------------
2014|1   |5        |56       |543
2014|2   |1154     |1234     |432
2014|3   |769      |123      |432
...

这可能吗?,查询怎么样?

2 个答案:

答案 0 :(得分:2)

您可以使用crosstab()功能(在tablefunc扩展名中)来解决此问题,该功能会转动您的数据。不幸的是,该功能只能在一个列上进行旋转,因此您必须稍微捏一下您的数据,然后取消它以获得所需的结果。

首先是软糖,而不是像这样产生两列:

extract(year from created_at) AS yy, 
extract(week from created_at) AS week

你应该将它们放在一个列中,如下所示:

extract(year from created_at) * 100 + extract(week from created_at) AS yr_wk

为您提供类似201401, 201402, 201403等的值。不错的属性是,它们就像单独的年份和周值一样排序,它们很容易组装,然后反汇编。

接下来,您运行crosstab()功能:

SELECT * FROM crosstab(
  'SELECT extract(year from created_at) * 100 + extract(week from created_at) AS yr_wk,
          id_country, count(id) AS cnt
   FROM property GROUP BY 1, 2 ORDER BY 1, 2',
  'SELECT s FROM generate_series(1, 7) s'
  ) AS (yr_wk int, c1 int, c2 int, c3 int, c4 int, c5 int, c6 int, c7 int);

其中' c1' - ' c7'是您所在国家/地区的名称。

然后填写你所做的yr_wk值:

SELECT yr_wk / 100 AS yy, yr_wk % 100 AS week, c1, c2, c3, c4, c5, c6, c7
FROM (
  << crosstab query from above >>
) sub
ORDER BY 1, 2;

答案 1 :(得分:2)

没有任何扩展的替代解决方案:

bower cache clean

如果您使用的是pg 9.4或更高版本,则可以替换

>= 1.0.8

SELECT 
  EXTRACT(YEAR FROM created_at) AS yy, 
  EXTRACT(WEEK FROM created_at) AS week, 
  COUNT(CASE WHEN id_country = 1 THEN id ELSE null END) AS country_1,
  COUNT(CASE WHEN id_country = 2 THEN id ELSE null END) AS country_2,
  COUNT(CASE WHEN id_country = 3 THEN id ELSE null END) AS country_3,
  ...
  COUNT(CASE WHEN id_country = 7 THEN id ELSE null END) AS country_7,
FROM property 
GROUP BY week, yy 
ORDER BY yy, week ASC;

等等。