下午好,我正在使用POSTGRESql 9.2版,并且试图使用交叉表函数来转置表上的两列,以便以后可以将其连接到其他SELECT查询中。
我已经安装了tablefunc扩展名。
但是,我不断收到此“返回和SQL元组描述不兼容”错误,这似乎是由于类型转换造成的。
我不需要它们是特定类型。
我原来的SELECT查询是这个
SELECT inventoryid, ttype, tamount
FROM inventorytesting
哪个给我以下结果:
inventoryid ttype tamount
2451530088940460 7 0.2
2451530088940460 2 0.5
2451530088940460 8 0.1
2451530088940460 1 15.7
8751530077940461 7 0.7
8751530077940461 2 0.2
8751530077940461 8 1.1
8751530077940461 1 19.2
我的目标是像这样:
inventoryid 7 2 8 1
8751530077940461 0.7 0.2 1.1 19.2
2451530088940460 0.2 0.5 0.1 15.7
“ ttype”字段具有49个固定的不同值,例如“ 7”,“ 2”,“ 8”,“ 1”。
“ tamount”字段根据“ inventoryid”字段的不同而有所不同,但即使其值为零,也始终有49个。它永远不会为“ null”。
我尝试了一些可以在互联网上找到的变化,总结如下:
SELECT *
FROM crosstab (
$$SELECT inventoryid, ttype, tamount
FROM inventorytesting
WHERE inventoryid = '2451530088940460'
ORDER BY inventoryid, ttype$$
)
AS ct("inventoryid" text,"ttype" smallint,"tamount" numeric)
库存测试表上的字段类型为
select column_name, data_type from information_schema.columns
where table_name = 'inventorytesting'
结果:
column_name data_type
id bigint
ttype smallint
tamount numeric
tunit text
tlessthan smallint
plantid text
sessiontime bigint
deleted smallint
inventoryid text
docdata text
docname text
labid bigint
任何指针都很棒。
答案 0 :(得分:0)
结果表定义必须包含您期望的表结构-透视表-而不是给定表的结构:
SELECT *
FROM crosstab(
$$SELECT inventoryid, ttype, tamount
FROM inventorytesting
WHERE inventoryid = '2451530088940460'
ORDER BY inventoryid, ttype$$
)
AS ct("inventoryid" text,"type1" numeric,"type2" numeric,"type7" numeric,"type8" numeric)
另外,不需要使用crosstab
函数。您只需使用标准的CASE
函数即可实现枢纽:
SELECT
inventoryid,
SUM(CASE WHEN ttype = 1 THEN tamount END) AS type1,
SUM(CASE WHEN ttype = 2 THEN tamount END) AS type2,
SUM(CASE WHEN ttype = 7 THEN tamount END) AS type7,
SUM(CASE WHEN ttype = 8 THEN tamount END) AS type8
FROM
inventorytesting
GROUP BY 1
如果您使用的是9.4或更高版本,则可以使用Postgres专用的FILTER
子句:
SELECT
inventoryid,
SUM(tamount) FILTER (WHERE ttype = 1) AS type1,
SUM(tamount) FILTER (WHERE ttype = 2) AS type2,
SUM(tamount) FILTER (WHERE ttype = 7) AS type7,
SUM(tamount) FILTER (WHERE ttype = 8) AS type8
FROM
inventorytesting
GROUP BY 1
答案 1 :(得分:0)
使用crosstab
,您可以定义实际结果表(基本上是数据透视表的结果)。输入查询定义三列,然后将其处理为:
对于您而言,crosstab
因此需要定义为:
ct(
"inventoryid" text,
"tamount_1" numeric,
"tamount_2" numeric,
"tamount_3" numeric,
...
)
然后,列标题将按照内部查询的ttype
所定义的顺序与列ORDER BY
的某个值相关联。
crosstab
的问题是缺少ttype
的值(例如,为4
返回了一些值,但没有为3
返回),结果列将为{{1 }},1
,2
,...,其中缺少4
。在这里,您必须确保(如果需要一致的输出)内部查询至少返回3
行(例如,通过NULL
)。