PostgreSQL和列到行

时间:2015-11-13 12:26:15

标签: postgresql unpivot

我有一张桌子(在PostgreSQL 9.3中),按城市年龄分组的人数如下:

city | year | sex | age_0 | age_1 | age_2 | ... | age_115
---------------------------------------------------------
city1| 2014 |   M | 12313 | 23414 | 52345 | ... |       0
city1| 2014 |   F | 34562 | 23456 | 53456 | ... |       6
city2| 2014 |   M |     3 |     2 |     2 | ... |      99

我想将列拆分为行,最后是这样的行:

city | year | sex | age | amount | age_group
--------------------------------------------
city1| 2014 |   M |   0 |  12313 | 0-6
city1| 2014 |   M |   1 |  23414 | 0-6
city1| 2014 |   M |   2 |  52345 | 0-6
city1| 2014 |   M | ... |    ... | ...
city1| 2014 |   M | 115 |      0 | 7-115

等等。我知道我可以用几个(很多)查询和UNION来做到这一点,但我想知道是否有一个更优雅(更少剪切' n粘贴)的方式进行这样的查询?

1 个答案:

答案 0 :(得分:1)

使用数组和不需要的

select city, 
       year, 
       sex,  
       unnest(array[age_0 , age_1 , age_2 , ..., age_115]) as amount,
       unnest(array[ 0 , 1 , 2 , ... ,  115]) as age 
from mytable

对于大型数据集,这可能很慢

快速查看,已经提出了许多类似的问题,一个很好的指导,可以动态生成您需要的查询...为您贴上link

生成查询IDiea

SELECT 'SELECT city , year , sex ,  unnest(ARRAY[' || string_agg(quote_ident(attname) , ',') || ']) AS amount  from mytable' AS sql
FROM   pg_attribute  
WHERE  attrelid = 'mytable'::regclass  and attname ~ 'age_'
AND    attnum > 0
AND    NOT attisdropped
GROUP  BY attrelid;