有谁知道如何在 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
这可能吗?
每个数据库安装 一次 附加模块 tablefunc ,它提供了功能。从 Postgres 9.1 开始,您可以使用: __crosstab()CREATE EXTENSION
tablefunc
crosstab()
CREATE EXTENSION
CREATE EXTENSION IF NOT EXISTS tablefunc;
CREATE TABLE tbl ( section text , status text , ct integer -- "count" is a reserved word in standard SQL ); INSERT INTO tbl VALUES ('A', 'Active', 1), ('A', 'Inactive', 2) , ('B', 'Active', 4), ('B', 'Inactive', 5) , ('C', 'Inactive', 7); -- ('C', 'Active') is missing
crosstab(text)有 _ 1 个_ 输入参数:
crosstab(text)
SELECT * FROM crosstab( 'SELECT section, status, ct FROM tbl ORDER BY 1,2' -- needs to be "ORDER BY 1,2" here ) AS ct ("Section" text, "Active" int, "Inactive" int);
回报:
Section | Active | Inactive ---------+--------+---------- A | 1 | 2 B | 4 | 5 C | 7 | -- !!
C
7
crosstab(text, text)有 _ 2 个_ 输入参数:
crosstab(text, text)
SELECT * FROM crosstab( 'SELECT section, status, ct FROM tbl ORDER BY 1,2' -- could also just be "ORDER BY 1" here **, $$VALUES ('Active'::text), ('Inactive')$$** ) AS ct ("Section" text, "Active" int, "Inactive" int);
Section | Active | Inactive ---------+--------+---------- A | 1 | 2 B | 4 | 5 C | | 7 -- !!
注意 的正确结果C。
第二 个参数 可以是任何查询,每个属性返回 一行 ,匹配最后列定义的顺序。通常,您会希望从基础表中查询不同的属性,如下所示:
'SELECT DISTINCT attribute FROM tbl ORDER BY 1'
手册上是这样的。
由于无论如何您都必须拼出列定义列表中的所有列(预定义的变体除外),因此在如下所示的表达式中提供简短列表通常更有效:crosstab _N_ ()``VALUES
crosstab _N_ ()``VALUES
$$VALUES ('Active'::text), ('Inactive')$$)
或者(不在手册中):
$$SELECT unnest('{Active,Inactive}'::text[])$$ -- short syntax for long lists
我使用 美元报价 使报价更容易。
只要值列的文本表示是目标类型的有效输入,您甚至可以输出具有 不同 数据类型的列。crosstab(text, text)这样,您可能具有不同的属性 kind 和 output text,等date,numeric用于各自的属性。手册章节 crosstab(text, text) 末尾有一个代码示例。
text
date
numeric
db <>在这里摆弄
多余的输入行的处理方式不同 -(section, status)在上面的示例中,相同(“row_name”,“category”)组合的重复行。
(section, status)
1 参数 表单从左到右填写可用值列。多余的值被丢弃。 较早的输入行获胜。
2 参数 形式将每个输入值分配给其专用列,覆盖任何先前的分配。 稍后输入行获胜。
通常,您一开始就没有重复项。但是,如果您这样做了,请根据您的要求仔细调整排序顺序 - 并记录发生的情况。 如果您不在乎,也可以快速获得任意结果。请注意效果。
\crosstabview
Postgres 9.6 将此元命令添加到其默认交互式终端psql中。您可以运行将用作第一个crosstab()参数的查询并将其提供给\crosstabview(立即或在下一步中)。像:
db=> SELECT section, status, ct FROM tbl \crosstabview
与上面类似的结果,但它是 客户端 专有的表示功能。输入行的处理方式略有不同,因此ORDER BY不是必需的。手册中的详细信息\crosstabview。该页面底部有更多代码示例。
ORDER BY
Daniel Vérité(psql 功能的作者)对 dba.SE 的相关回答: