PostgreSQL 和列到行

PostgreSQL and columns to rows

我有一个 table(在 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 来做到这一点,但我想知道是否有更优雅(更少涉及剪切和粘贴)的方式来执行这样的查询?

使用数组并取消嵌套

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;