sql - POSTGRES 将周列转为行?

标签 sql postgresql unpivot generate-series

我的预测表存储当前周,然后是 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 LATERALgenerate_series() 以生成所需的行。使用 ARRAY constructor就像您已经在子查询中一样。生成的索引 w 用于将周添加到基准日期以及访问相应的数组项。请注意一个潜伏的 off-by-1 错误,因为 Postgres 数组索引默认是从 1 开始的。相关:

由于 week_current_date 似乎允许 NULL 值,您可能需要使用 ORDER BY week_current_date DESCNULLS LAST 对最后带有 NULL 的行进行排序,否则这些行将排在最前面。见:

关于sql - POSTGRES 将周列转为行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46575075/

相关文章:

mysql - MySQL 查询中的 GROUP BY 子句仅在某些情况下会导致我的连接崩溃

SQL - PostgreSQL - 查找预订日历中的空白

Postgresql 模式匹配

google-apps-script - 如何在 Google Apps 脚本中转置和拆分?

mysql - 是否可以以转置格式从表中检索数据

mysql - 如何在考虑记录序列的情况下对列进行 GROUP BY?

php - 如何防止 PHP 中的 SQL 注入(inject)?

sql - 如何在 SQL 中获取 "top X with the rest"?

SQL Server 2008条件选择输出多个真值