使用交叉表将行转换为列失败

时间:2014-12-15 10:32:53

标签: sql postgresql crosstab

我有一个postgres表,格式如下:

id            key             value
-------------------------------------
a              1               p
b              2               q
c              3               r
a              2               s

我想将其转换为以下格式:

id            1             2            3
--------------------------------------------
a             p             s
b                           q
c                                        r

我正在尝试使用以下crosstab()查询来执行此操作:

create extension tablefunc;

select * from crosstab(
'select id, key, value
from table
order by 1,2')
as ct(id text, key integer, value text);

但是,它失败并出现以下异常:

ERROR:  return and sql tuple descriptions are incompatible
********** Error **********

ERROR: return and sql tuple descriptions are incompatible
SQL state: 42601

我在这里缺少什么?

更新:表格中有大约25个键。

3 个答案:

答案 0 :(得分:2)

必须提供第二个参数,其中包含可能值列表,以允许每个结果行中缺少值:

SELECT * 
FROM   crosstab(
         'SELECT id, key, value
          FROM   tbl
          ORDER  BY 1, 2'
       , 'SELECT generate_series(1,25)'  -- assuming your key is type integer
       ) AS ct(id text
       , "1" text, "2" text, "3" text, "4" text, "5" text
       , "6" text, "7" text, "8" text, "9" text, "10" text
       , "11" text, "12" text, "13" text, "14" text, "15" text
       , "16" text, "17" text, "18" text, "19" text, "20" text
       , "21" text, "22" text, "23" text, "24" text, "25" text);

详细说明:

如果您厌倦了输入冗长的列定义列表,请考虑以下相关(高级)答案:

答案 1 :(得分:1)

试试这个:

SELECT * 
  FROM crosstab(
                'SELECT id, 
                        key, 
                        value
                   FROM table
               ORDER BY 1, 2'
               )
    AS CT(id text, one text, two text, three text);

您需要as ct()中的最后四个列名称,请查看here了解详情

答案 2 :(得分:0)

请参考以下代码。
我希望它对你有用。

SELECT * 
  FROM crosstab(
                'SELECT id, 
                        key, 
                        "value"
                   FROM table                   
               ORDER BY  1,2'
               )
    AS t(id text, "1" text,"2" text, "3" text);

如果你还不够,你也可以在这个链接上提到类似的问题。 PostgreSQL says "return and sql tuple descriptions are incompatible"