将数据从长格式转换为宽格式。SQL 必须返回 row_name、category 和 value 列:
SQL
CREATETABLEct(idSERIAL,rowidTEXT,attributeTEXT,valueTEXT);INSERTINTOct(rowid,attribute,value)VALUES('test1','att1','val1'),('test1','att2','val2'),('test1','att3','val3'),('test2','att1','val5'),('test2','att2','val6'),('test2','att3','val7');SELECT*FROMcrosstab('SELECT rowid, attribute, value FROM ct ORDER BY 1,2')ASct(row_nametext,category_1text,category_2text,category_3text);row_name|category_1|category_2|category_3----------+------------+------------+------------
test1|val1|val2|val3test2|val5|val6|val7
输入查询应始终使用 ORDER BY 1,2 以确保正确分组。
超出可用值范围的输出列将填充 null。
crosstab(text, text) – 双参数透视(含类别列表)
处理某些分组可能缺少部分类别数据的情况:
SQL
CREATETABLEsales(yearint,monthint,qtyint);INSERTINTOsalesVALUES(2007,1,1000),(2007,2,1500),(2007,7,500),(2007,11,1500),(2007,12,2000),(2008,1,1000);SELECT*FROMcrosstab('SELECT year, month, qty FROM sales ORDER BY 1','SELECT m FROM generate_series(1,12) m')AS(yearint,"Jan"int,"Feb"int,"Mar"int,"Apr"int,"May"int,"Jun"int,"Jul"int,"Aug"int,"Sep"int,"Oct"int,"Nov"int,"Dec"int);year|Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec------+------+------+-----+-----+-----+-----+-----+-----+-----+-----+------+------
2007|1000|1500|||||500||||1500|20002008|1000|||||||||||
源 SQL 可以在 row_name 与 category/value 之间包含"额外"列。
crosstab2, crosstab3, crosstab4 – 预定义封装函数
预构建的封装函数,无需编写 FROM 子句(仅支持文本输入/输出):
SQL
SELECT*FROMcrosstab3('SELECT rowid, attribute, value FROM ct ORDER BY 1,2');