如何创建以多个列为数据透视的PostgreSQL数据透视表?

如何创建以多个列为数据透视的PostgreSQL数据透视表?,sql,postgresql,pivot-table,crosstab,Sql,Postgresql,Pivot Table,Crosstab,我一直在探索PostgreSQL的tablefunc中的crosstab()函数,作为生成透视表的一种方法 这很好,但似乎只适用于最基本的用例。它通常只支持三列输入: 保持不变的值列,如行标签 以数据轴为轴的一列值,将成为新的列名 一列值,这些值将成为其各自新轴心列的值 基本上是这样的: +------+----------+-------+ | ITEM | STATUS | COUNT | +------+----------+-------+ | foo | active |

我一直在探索PostgreSQL的
tablefunc
中的
crosstab()
函数,作为生成透视表的一种方法

这很好,但似乎只适用于最基本的用例。它通常只支持三列输入:

  • 保持不变的值列,如行标签
  • 以数据轴为轴的一列值,将成为新的列名
  • 一列值,这些值将成为其各自新轴心列的值
  • 基本上是这样的:

    +------+----------+-------+
    | ITEM |  STATUS  | COUNT |
    +------+----------+-------+
    | foo  | active   |    12 |
    | foo  | inactive |    17 |
    | bar  | active   |    20 |
    | bar  | inactive |     4 |
    +------+----------+-------+
    
    。。。制作这个:

    +------+--------+--------+----------+
    | ITEM | STATUS | ACTIVE | INACTIVE |
    +------+--------+--------+----------+
    | foo  | active |     12 |       17 |
    | bar  | active |     20 |        4 |
    +------+--------+--------+----------+
    
    但是更复杂的用例呢?如果您有:

  • 您希望在输出中保持原样的多个输入列
  • 要将多个输入列透视到新列中吗
  • 如下例所示:

    +--------+-----------------+---------+--------+-------+------------------+
    | SYSTEM |  MICROSERVICE   |  MONTH  | METRIC | VALUE | CONFIDENCE_LEVEL |
    +--------+-----------------+---------+--------+-------+------------------+
    | batch  | batch-processor | 2019-01 | uptime |    99 |                2 |
    | batch  | batch-processor | 2019-01 | lag    |    20 |                1 |
    | batch  | batch-processor | 2019-02 | uptime |    97 |                2 |
    | batch  | batch-processor | 2019-02 | lag    |    35 |                2 |
    +--------+-----------------+---------+--------+-------+------------------+
    
    其中前三列应按每行的原样进行(无分组或聚合)。而
    metric
    列有两个相关列(即
    value
    confidence\u level
    )作为它的轴心

    +--------+-----------------+---------+--------------+-------------------+-----------+----------------+
    | SYSTEM |  MICROSERVICE   |  MONTH  | UPTIME_VALUE | UPTIME_CONFIDENCE | LAG_VALUE | LAG_CONFIDENCE |
    +--------+-----------------+---------+--------------+-------------------+-----------+----------------+
    | batch  | batch-processor | 2019-01 |           99 |                 2 |        20 |              1 |
    | batch  | batch-processor | 2019-02 |           97 |                 2 |        35 |              2 |
    +--------+-----------------+---------+--------------+-------------------+-----------+----------------+
    

    我不确定这是否仍然符合“透视表”的严格定义。但是,使用
    crosstab()
    ,或者任何其他现成的PostgreSQL函数,这样的结果可能吗?如果不是,那么如何使用自定义PL/pgSQL函数生成它?谢谢

    您可以尝试使用条件聚合

    select system,MICROSERVICE , MONTH,
    max(case when METRIC='uptime' then VALUE end) as uptime_value,
    max(case when METRIC='uptime' then CONFIDENCE_LEVEL end) as uptime_confidence,
    max(case when METRIC='lag' then VALUE end) as lag_value,
    max(case when METRIC='lag' then CONFIDENCE_LEVEL end) as lag_confidence
    from tablename
    group by system,MICROSERVICE , MONTH
    

    另一种方法(我曾经使用过)是将数据写入一个文件,使用单独的实用程序以所需的格式对其进行交叉制表,然后将结果导入一个新表。

    SQL不是设计用来做这种事情的。这在前端代码中做得更好。或者将动态列聚合为一个JSON值,太棒了,谢谢!我对“数据透视表”这个术语很感兴趣(我不能100%肯定这是因为有多个“数据透视”)。我本应该退一步,考虑如何实现实际结果,而不必为指导某种方法的术语而烦恼。