3

我有一个这样的查询:

select to_date(to_char(registime, 'YYYY-MM'),'YYYY-MM') as dt,count(id) as total_call  
from all_info 
where alarm_id is null
group by dt   
order by dt

结果是这样的:

dt          total_call      
2011-03-01     45
2011-04-01     61
2011-05-01     62
2011-06-01     41
2011-07-01     48
2011-08-01     42
2011-09-01     28
2011-10-01     39

我想要下面演示中的结果,表格形式:

2011-03-01   2011-04-01  2011-05-01  2011-06-01  ..........
   45            61          62          41

我想使用crosstab,但它似乎不起作用?

4

1 回答 1

3

查看 contrib 模块tablefunc。它提供了您正在寻找的那种数据透视表功能。请参阅此处的手册

请按照此处或@Paul Tomblin 在他上面的评论中建议的文章中的安装说明进行操作。

那么你的函数可能如下所示:

SELECT *
  FROM crosstab($$
SELECT 'total_calls'::text AS col_name
      ,to_char(registime, '"x"YYYY_MM_01') as dt
      ,count(id) as total_call  
FROM   all_info 
WHERE  alarm_id is null
GROUP  BY dt   
ORDER  BY dt
$$)
AS ct(
 call_day text
,x2011_03_01 int8
,x2011_04_01 int8
,x2011_05_01 int8
,x2011_06_01 int8
,x2011_07_01 int8
,x2011_08_01 int8
,x2011_09_01 int8
,x2011_10_01 int8);

输出:

  call_day   | x2011_03_01 | x2011_04_01 | x2011_05_01 | x2011_06_01 | x2011_07_01 | x2011_08_01 | x2011_09_01 | x2011_10_01
-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------
 total_calls |           1 |           4 |           4 |           2 |           1 |           5 |           1 |           1

列名不能以数字开头(或者你必须双引号),这就是为什么我在日期前加上 x。我还简化了您的查询。
您可以将其包装在视图或函数中以供重复使用。
也许是一个动态调整列名和 EXECUTE 的 plpgsql 函数。

此相关答案中的更多详细信息、解释和链接

于 2011-10-26T15:11:30.827 回答