是否可以根据 PostgreSQL 中的输入列生成列
Is it possible to generate columns based on input columns in PostgreSQL
我在 PostgreSQL 中有一个像这样的 table,有 3 个初始列,分别称为 Project、Size 和 开始日期(见下文):
项目
尺寸
开始日期
项目 1
88
2020-06-15
项目 2
105
2020-03-01
我需要在 StartDate 列旁边添加 12 列 并扩展初始 table 到 15 列 。所有新列代表给定年份(2020 年)的月份,它们将包含 0 和根据从 Size 和 StartDate 列派生的条件逻辑计算的值.条件如下:如果 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;
我在 PostgreSQL 中有一个像这样的 table,有 3 个初始列,分别称为 Project、Size 和 开始日期(见下文):
项目 | 尺寸 | 开始日期 |
---|---|---|
项目 1 | 88 | 2020-06-15 |
项目 2 | 105 | 2020-03-01 |
我需要在 StartDate 列旁边添加 12 列 并扩展初始 table 到 15 列 。所有新列代表给定年份(2020 年)的月份,它们将包含 0 和根据从 Size 和 StartDate 列派生的条件逻辑计算的值.条件如下:如果 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;