Postgres 交叉表动态列数

Posted

技术标签:

【中文标题】Postgres 交叉表动态列数【英文标题】:Postgres Crosstab Dynamic Number of Columns 【发布时间】:2015-12-29 00:18:22 【问题描述】:

在 Postgres 9.4 中,我有一个这样的表:

id  extra_col  days value
--  ---------  ---  -----
1   rev          0      4
1   rev         30      5
2   cost        60      6

我想要这个旋转的结果

id  extra_col   0  30  60
--  ---------  --  --  --
1   rev         4   5   
2   cost                6

使用交叉表很简单。 但我想要以下规格:

day 列将是动态的。有时增量为 1、2、3(天)、0、30、60 天(会计月),有时以 360、720(会计年)为增量。 天数范围是动态的。 (例如,0..500 天与 1..10 天)。 前两列是静态的(id 和 extra_col) 所有动态列的返回类型将保持相同类型(在本例中为integer

以下是我探索过的解决方案,但没有一个对我有用,原因如下:

    Automatically creating pivot table column names in PostgreSQL - 需要两次访问数据库。 Using crosstab_hash - 不是动态的

在我探索过的所有解决方案中,似乎唯一允许在一次访问数据库中发生这种情况的解决方案需要运行相同的查询 3 次。有没有办法在crosstab 函数中将查询存储为CTE

SELECT *
FROM
CROSSTAB(
    --QUERY--,
    $$--RUN QUERY AGAIN TO GET NUMBER OF COLUMNS--$$
)
as ct (
    --RUN QUERY AGAIN AND CREATE STRING OF COLUMNS WITH TYPE--
)

【问题讨论】:

为什么不两次访问数据库?单次访问 db 和动态输出列数是互斥的。除非您将动态输出列嵌套到单个列中(如 Oracle 的 pivot xml 运算符)并让客户端取消嵌套它。 【参考方案1】:

每个基于任何内置功能的解决方案都需要知道许多输出列。 PostgreSQL 规划器需要它。有基于游标的解决方法 - 它只是一种方法,如何从 Postgres 获得真正动态的结果。

这个例子比较长而且不可读(SQL确实不支持交叉表),所以我不会在这里重写博客http://okbob.blogspot.cz/2008/08/using-cursors-for-generating-cross.html的代码。

【讨论】:

以上是关于Postgres 交叉表动态列数的主要内容,如果未能解决你的问题,请参考以下文章

MySQL将行转换为动态列数

MySQL将行转换为动态列数

Greenplum/Postgres 8 函数动态结果集?

如何在工作表中动态创建具有列数的数组,以删除多列中的重复项

Postgres 表选择多列并将结果(列)动态转换为行 - 将列转置为行

具有动态列名和多个输入列的 PostgreSQL 交叉表