我正在尝试从我的数据中获得以下内容:
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'数据结构不合理,因此很难准确了解这些列中的内容,因此将这些值硬编码到代码中并不容易
答案 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)