有没有人知道如何在PostgreSQL中创建交叉表查询?
例如,我有下表:
Section Status Count
A Active 1
A Inactive 2
B Active 4
B Inactive 5
我想查询返回以下交叉表:
Section Active Inactive
A 1 2
B 4 5
这可能吗?
6 回答
每个数据库安装一次additional module tablefunc,提供函数
crosstab()
. 从Postgres 9.1开始,您可以使用CREATE EXTENSION:改进了测试用例
简单形式 - 不适合缺少属性
crosstab(text)
带 1 输入参数:返回:
无需投射和重命名 .
注意
C
的 incorrect 结果:第一列填写了值7
. 有时,这种行为是可取的,但不适用于此用例 .简单表单也仅限于提供的输入查询中的三列:row_name,category,value . 如下面的2参数替代方案中没有额外列的空间 .
安全表格
crosstab(text, text)
带 2 输入参数:返回:
注意
C
的正确结果 .第二个参数可以是任何查询,每个属性返回一行,最后匹配列定义的顺序 . 通常,您需要查询基础表中的不同属性,如下所示:
这是在手册中 .
由于您必须拼写列定义列表中的所有列(预定义的
crosstabN()
变体除外),因此在VALUES
表达式中提供短列表通常更为有效,如下所示:或(不在手册中):
我使用了dollar quoting来简化报价 .
您甚至可以使用带有
crosstab(text, text)
的 different data types 列输出 - 只要值列的文本表示是目标类型的有效输入 . 这样,您可能具有不同类型的属性,并为各个属性输出text
,date
,numeric
等 . 在chapter crosstab(text, text) in the manual的末尾有一个代码示例 .db <>小提琴here
高级示例
Pivot on Multiple Columns using Tablefunc - 同时展示"extra columns"
Dynamic alternative to pivot with CASE and GROUP BY
psql中
\ crosstabview
Postgres 9.6 将此元命令添加到其默认交互终端psql . 您可以运行您将用作第一个
crosstab()
参数的查询并将其提供给\crosstabview
(立即或在下一步中) . 喜欢:与上面类似的结果,但它只是客户端的表示功能 . 输入行的处理方式略有不同,因此不需要
ORDER BY
. \crosstabview in the manual.的详细信息该页面底部有更多代码示例 .关于dba.SE的相关答案,作者:DanielVérité(psql特性的作者):
之前接受的答案已过时 .
crosstab(text, integer)
的变体已过时 . 第二个integer
参数被忽略 . 我引用current manual:无需投射和重命名 .
如果某行没有所有属性,则会失败 . 请参阅上面两个输入参数的安全变体,以正确处理缺少的属性 .
crosstab()
的单参数形式中需要ORDER BY
. The manual:您可以使用additional module tablefunc的
crosstab()
函数 - 您必须为每个数据库安装一次 . 从PostgreSQL 9.1开始,您可以使用CREATE EXTENSION:在你的情况下,我相信它看起来像这样:
使用JSON聚合的解决方案:
对不起,这是不完整的,因为我不能在这里测试,但它可能会让你走向正确的方向 . 我正在翻译我使用的一些类似的查询:
我正在使用的代码是:
这将返回一个typeID,最高价格出价和最低价格以及两者之间的差异(正差异意味着可以买入少于可以出售的东西) .
Crosstab
功能在tablefunc
扩展名下可用 . 您必须为数据库创建一次此扩展 .CREATE EXTENSION
tablefunc
;您可以使用以下代码使用交叉表创建数据透视表: