Postgres交叉混淆

时间:2015-10-20 15:47:10

标签: postgresql crosstab

我正在尝试从我的数据中获得以下内容:

docid,  yyyy,   tiOne,  tiTwo,  tiThree,  tiFour
d1      2011    txtA    txtB    txtC
d2      2012    txtD    txtE    txtF      txtG
d3      2013    txtH    txtI    txtJ
d4      2013    txtK

这是重建我的数据的方法:

CREATE TEMP TABLE t (
  docid   text
, yyyy    int
, timark  text
, txtmark text
);

INSERT INTO t VALUES 
  ('d1', 2011, 'tiOne', 'txtA'), 
  ('d1', 2011, 'tiTwo', 'txtB'), 
  ('d1', 2011, 'tiThree', 'txtC'), 
  ('d2', 2012, 'tiOne', 'txtD'),
  ('d2', 2012, 'tiTwo', 'txtE'),
  ('d2', 2012, 'tiThree', 'txtF'),
  ('d2', 2012, 'tiFour', 'txtG'),
  ('d3', 2013, 'tiOne', 'txtH'), 
  ('d3', 2013, 'tiTwo', 'txtI'), 
  ('d3', 2013, 'tiThree', 'txtJ'), 
  ('d4', 2013, 'tiOne', 'txtK')
;

这是我的代码

select *
FROM   crosstab(
      'SELECT docid, timark, txtmark
       FROM   t
       ORDER  BY 1,2')  -- needs to be "ORDER BY 1,2" here
AS ct ("docid" text, "timark" text, "txtmark" text);

但是我的输出完全混乱如下:

docid timark txtmark
d1    txtA   txtC
d2    txtG   txtD
d3    txtH   txtJ
d4    txtK   

'tiOne'数据结构不合理,因此很难准确了解这些列中的内容,因此将这些值硬编码到代码中并不容易

1 个答案:

答案 0 :(得分:1)

交叉表查询别名应包含结果集的列名和类型。 源查询的结果应按两列排序:行标识符(docid)和类别标识符(timark)。 不幸的是,类别名称的字母顺序不是预期的。

在这种情况下,使用带有两个参数的crosstab函数的形式。 第二个参数是一个选择预期顺序中所有类别的查询。 这种crosstab形式还允许添加其他列(yyyy)并正确显示不完整的数据。

select *
FROM crosstab(
    $$ SELECT docid, yyyy, timark, txtmark
    FROM t
    ORDER BY 1 $$,
    $$ values ('tiOne'), ('tiTwo'), ('tiThree'), ('tiFour') $$)
AS ct ("docid" text, "yyyy" text, "tiOne" text, "tiTwo" text, "tiThree" text, "tiFour" text);

 docid | yyyy | tiOne | tiTwo | tiThree | tiFour 
-------+------+-------+-------+---------+--------
 d1    | 2011 | txtA  | txtB  | txtC    | 
 d2    | 2012 | txtD  | txtE  | txtF    | txtG
 d3    | 2013 | txtH  | txtI  | txtJ    | 
 d4    | 2013 | txtK  |       |         | 
(4 rows)