大量列的 Un-Pivoting Postgres

Un-Pivoting Postgres for a large number of columns

所以我一直在寻找用于透视的交叉表,但不确定是否有更具可扩展性的方法来做到这一点。

现在我的结构看起来像

Date Amount1 Amount2 Amount3
Date 1 2 1
Date 1 3 2
Date 2 4 1
Date 3 5 2

我想把它变成这种格式

Date Name Amount
Date Amount1 1

等等等等

现在我遇到的问题是 Amount1 可以是动态的,并且可以随着时间的推移不断增加。我试图不必对其进行硬编码,因为现在大约有 40 列,而且我可以看到它随着时间的推移而增加

是的,除了列前缀之外,无需对任何内容进行硬编码是可能的:

SELECT t.date, s3."key" as name, s3."value" as amount
FROM t
,LATERAL (SELECT *
          FROM (SELECT ROW_TO_JSON(t.*)) s(c)
          ,LATERAL JSON_EACH(s.c) s2
          WHERE s2."key" LIKE 'amount%') s3;

db<>fiddle demo

输出:

+-------------+----------+-------+
|    date     |   key    | value |
+-------------+----------+-------+
| 2021-01-01  | amount1  |     1 |
| 2021-01-01  | amount2  |     2 |
| 2021-01-01  | amount3  |     3 |
| 2021-01-02  | amount1  |     1 |
| 2021-01-02  | amount2  |     3 |
| 2021-01-02  | amount3  |     2 |
| 2021-01-03  | amount1  |     2 |
| 2021-01-03  | amount2  |     4 |
| 2021-01-03  | amount3  |     1 |
| 2021-01-04  | amount1  |     3 |
| 2021-01-04  | amount2  |     5 |
| 2021-01-04  | amount3  |     2 |
+-------------+----------+-------+

工作原理:

  1. 从行
  2. 生成json
  3. 解析json并仅选择键具有特定前缀的值

编辑:(戈登)

我认为不需要子查询。查询可以简化为:

SELECT t.date, je.key, je.value
FROM t cross join lateral
     row_to_json(t.*) rtj(r) cross join lateral
     JSON_EACH(rtj.r) je
WHERE je."key" LIKE 'amount%';