我的预测表存储当前周,然后是 26 周的预测量:
CREATE TABLE forecast_listings (
product integer NOT NULL
, current_week_date date
, weekplus0 integer NOT NULL DEFAULT 0
, weekplus1 integer NOT NULL DEFAULT 0
, weekplus2 integer NOT NULL DEFAULT 0
, weekplus3 integer NOT NULL DEFAULT 0
, weekplus4 integer NOT NULL DEFAULT 0
-- etc
, weekplus24 integer NOT NULL DEFAULT 0
, weekplus25 integer NOT NULL DEFAULT 0
);
例如预测单个项目,我选择具有最近 current_week_date
的一行,然后查看相对周数。
SELECT
unnest(
array[
to_char(week_current_date, 'YYYY-MM-DD'),
to_char(week_current_date + interval '1 weeks', 'YYYY-MM-DD'),
to_char(week_current_date + interval '2 weeks', 'YYYY-MM-DD'),
to_char(week_current_date + interval '3 weeks', 'YYYY-MM-DD'),
to_char(week_current_date + interval '4 weeks', 'YYYY-MM-DD')
-- ...all the way to 25
]
) AS "Week",
unnest(
array[
weekplus0,
weekplus1,
weekplus2,
weekplus3,
weekplus4
-- ...all the way to 25
]
) AS "Count"
FROM (
SELECT * FROM forecast_listings
WHERE product_id = 1
ORDER BY week_current_date DESC
LIMIT 1
) as row
我想用 Postgres 做到这一点,本质上是获取一行并将每个星期的数字转换为带有日期列和计数列的行:
week, count
2017-10-01,100
2017-10-08,200
2017-10-15,150
etc.
最佳答案
SELECT to_char(f.week_current_date + interval '1 week' * w, 'YYYY-MM-DD')
, arr[w+1]
FROM (
SELECT week_current_date
, ARRAY[weekplus0, weekplus1, weekplus2, weekplus3] AS arr -- add all 26
FROM forecast_listings
WHERE product_id = 1
ORDER BY week_current_date DESC NULLS LAST -- ?
LIMIT 1
) f
CROSS JOIN LATERAL generate_series(0, 25) w;
关键特性是 CROSS JOIN LATERAL
到 generate_series()
以生成所需的行。使用 ARRAY constructor就像您已经在子查询中一样。生成的索引 w
用于将周添加到基准日期以及访问相应的数组项。请注意一个潜伏的 off-by-1 错误,因为 Postgres 数组索引默认是从 1 开始的。相关:
- What is the difference between LATERAL and a subquery in PostgreSQL?
- How to unpivot a table in PostgreSQL
- PostgreSQL unnest() with element number
- Normalize array subscripts for 1-dimensional array so they start with 1
- Generate series of week intervals for given month
由于 week_current_date
似乎允许 NULL 值,您可能需要使用 ORDER BY week_current_date DESC
NULLS LAST
对最后带有 NULL 的行进行排序,否则这些行将排在最前面。见:
关于sql - POSTGRES 将周列转为行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46575075/