有谁知道如何在 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
这可能吗?
原文由 user151419 发布,翻译遵循 CC BY-SA 4.0 许可协议
每个数据库安装 一次 附加模块
tablefunc
,它提供功能crosstab()
。从 Postgres 9.1 开始,您可以使用CREATE EXTENSION
:改进的测试用例
简单的形式 - 不适合缺少的属性
crosstab(text)
带 1个 输入参数:回报:
C
的 错误 结果:值7
填写在第一列。有时,这种行为是可取的,但不适用于此用例。安全形式
crosstab(text, text)
有 2个 输入参数:回报:
注意
C
的正确结果。第二个参数 可以是任何查询,每个属性返回 _一行_,匹配最后列定义的顺序。通常,您会希望从基础表中查询不同的属性,如下所示:
手册上是这样的。
由于无论如何您都必须拼出列定义列表中的所有列(预定义的
crosstabN()
变体除外),因此在VALUES
表达式中提供短列表通常更有效如演示:或者(不在手册中):
我使用 美元报价 使报价更容易。
您甚至可以使用
crosstab(text, text)
输出具有 不同 数据类型 的列 - 只要值列的文本表示是目标类型的有效输入。这样,您可能具有不同类型的属性并输出text
,date
,numeric
等。 手册中的章节crosstab(text, text)
末尾有一个代码示例。_db<> 在这里 摆弄_
多余输入行的影响
多余的输入行的处理方式不同 - 相同(“row_name”,“category”)组合的重复行 -
(section, status)
在上面的例子中。1 参数 表单从左到右填写可用值列。多余的值被丢弃。
较早的输入行获胜。
2 参数 形式将每个输入值分配给其专用列,覆盖任何先前的分配。
稍后输入行获胜。
通常,您一开始就没有重复项。但如果您这样做,请根据您的要求仔细调整排序顺序 - 并记录发生的情况。
如果您不在乎,也可以快速获得任意结果。请注意效果。
高级示例
使用 Tablefunc 旋转多列- 还演示了提到的“额外列”
使用 CASE 和 GROUP BY 的动态替代方案
\crosstabview
在 psqlPostgres 9.6 将此元命令添加到其默认交互式终端 psql 中。您可以运行将用作第一个
crosstab()
参数的查询并将其提供给\crosstabview
(立即或在下一步中)。喜欢:与上面类似的结果,但它 _是客户端专有的表示功能_。输入行的处理方式略有不同,因此不需要
ORDER BY
。 手册中\crosstabview
的详细信息。 该页面底部有更多代码示例。Daniel Vérité(psql 功能的作者)对 dba.SE 的相关回答: