是否可以根据 PostgreSQL 中的输入列生成列

Is it possible to generate columns based on input columns in PostgreSQL

我在 PostgreSQL 中有一个像这样的 table,有 3 个初始列,分别称为 ProjectSize开始日期(见下文):

项目 尺寸 开始日期
项目 1 88 2020-06-15
项目 2 105 2020-03-01

我需要在 StartDate 列旁边添加 12 列 并扩展初始 table 到 15 列 。所有新列代表给定年份(2020 年)的月份,它们将包含 0 和根据从 SizeStartDate 列派生的条件逻辑计算的值.条件如下:如果 StartDate 属于特定月份,则该月份获得 value=Size 并且之后的每个下个月Value=Value-50 直到 Value >0。请检查以下预期结果:

项目 尺寸 开始日期 一月 二月 3 月 四月 六月 七月 八月 九月 十月 11 月 十二月
项目 1 88 2020-06-15 0 0 0 0 88 38 0 0 0 0 0 0
项目 2 105 2020-03-01 0 0 105 55 5 0 0 0 0 0 0 0

这可以用很多 CASE 表达式来完成:

SELECT project,
       size,
       startdate,
       CASE WHEN mon < 2
            THEN greatest(size - 50 * (1 - mon), 0)
            ELSE 0
       END AS jan,
       CASE WHEN mon < 3
            THEN greatest(size - 50 * (2 - mon), 0)
            ELSE 0
       END AS feb,
       CASE WHEN mon < 4
            THEN greatest(size - 50 * (3 - mon), 0)
            ELSE 0
       END AS mar,
       CASE WHEN mon < 5
            THEN greatest(size - 50 * (4 - mon), 0)
            ELSE 0
       END AS apr,
       CASE WHEN mon < 6
            THEN greatest(size - 50 * (5 - mon), 0)
            ELSE 0
       END AS may,
       CASE WHEN mon < 7
            THEN greatest(size - 50 * (6 - mon), 0)
            ELSE 0
       END AS jun,
       CASE WHEN mon < 8
            THEN greatest(size - 50 * (7 - mon), 0)
            ELSE 0
       END AS jul,
       CASE WHEN mon < 9
            THEN greatest(size - 50 * (8 - mon), 0)
            ELSE 0
       END AS aug,
       CASE WHEN mon < 10
            THEN greatest(size - 50 * (9 - mon), 0)
            ELSE 0
       END AS sep,
       CASE WHEN mon < 11
            THEN greatest(size - 50 * (10 - mon), 0)
            ELSE 0
       END AS oct,
       CASE WHEN mon < 12
            THEN greatest(size - 50 * (11 - mon), 0)
            ELSE 0
       END AS nov,
       CASE WHEN mon < 13
            THEN greatest(size - 50 * (12 - mon), 0)
            ELSE 0
       END AS dec
FROM (SELECT project,
             size,
             startdate,
             extract(month FROM startdate) AS mon
      FROM mytable) AS q;