postgres交叉/交互

时间:2013-01-29 16:03:49

标签: sql postgresql pivot crosstab unpivot

我想请求帮助..我有这张桌子

user_id  | Metric_1 | Metric_2 | Metric_3
------------------------------------------
1        | Jan      | 10       | yes
2        | Feb      | 10       | No
3        | Mar      | 20       | No
4        | Apr      | 30       | No
5        | May      | 40       | yes
6        | Jun      | 50       | No
7        | Jul      | 60       | No
8        | Aug      | 70       | yes
9        | Sep      | 80       | No
10       | Oct      | 90       | yes
11       | Nov      | 10       | No
12       | Dec      | 20       | No

我想在查询中得到这个结果,我正在使用postgres tablefunc交叉表,但我可以得到它有这个结果...希望你能帮助我

| January | February | March | April | May
 ---------------------------------------------------
| 10      | 10       | 20    |30     |40
| yes     | NO       | No    |yes    |No

1 个答案:

答案 0 :(得分:2)

对于此类转换,您可以取消隐藏,然后转移数据。对于unpivot,您可以使用UNION ALL查询,然后应用带有CASE表达式的聚合函数来转动数据:

select 
  max(case when metric_1 ='Jan' then value end) as Jan,
  max(case when metric_1 ='Feb' then value end) as Feb,
  max(case when metric_1 ='Mar' then value end) as Mar,
  max(case when metric_1 ='Apr' then value end) as Apr,
  max(case when metric_1 ='May' then value end) as May,
  max(case when metric_1 ='Jun' then value end) as Jun,
  max(case when metric_1 ='Jul' then value end) as Jul,
  max(case when metric_1 ='Aug' then value end) as Aug,
  max(case when metric_1 ='Sep' then value end) as Sep,
  max(case when metric_1 ='Oct' then value end) as Oct,
  max(case when metric_1 ='Nov' then value end) as Nov,
  max(case when metric_1 ='Dec' then value end) as "Dec"
from
(
  select user_id, metric_1, cast(metric_2 as varchar(10)) as value, 'Metric2' as col
  from yourtable
  union all
  select user_id, metric_1, metric_3 as value, 'Metric3' as col
  from yourtable
) src
group by col
order by col

请参阅SQL Fiddle with Demo

结果是:

| JAN | FEB | MAR | APR | MAY | JUN | JUL | AUG | SEP | OCT | NOV | DEC |
-------------------------------------------------------------------------
|  10 |  10 |  20 |  30 |  40 |  50 |  60 |  70 |  80 |  90 |  10 |  20 |
| yes |  No |  No |  No | yes |  No |  No | yes |  No | yes |  No |  No |