【问题标题】:Create date and hour columns from date range从日期范围创建日期和小时列
【发布时间】:2019-06-12 00:55:03
【问题描述】:

我想创建一个临时表,在其中给它一个开始和结束日期(定价)。然后结果是一列中的日期和另一列中的每一天的小时。

看起来像这样:

date       hour
------------------
1/17/19     1
1/17/19     2
1/17/19     3
   .        .
   .        .
1/17/19    24
1/18/19     1
1/18/19     2
1/18/19     3
   .        .
   .        .
   .        .

所以我似乎想在一个小时内使用 generate_series。但不确定如何将其与日期匹配。

这不是为我完成的:

WITH hrs AS (SELECT * FROM generate_series(1,24)),
pricedate AS (SELECT * FROM generate_series('2018-01-24', '2018-01-26', interval '1 day'))


SELECT pricedate, hrs
WHERE pricedate BETWEEN '2018-01-24' AND '2018-01-26'
ORDER BY pricedate, hour

【问题讨论】:

    标签: sql postgresql generate-series


    【解决方案1】:
    select d::date as date, extract(hour from d)::int+ 1 as hour
    from generate_series('2018-01-24', '2018-01-26 23:00', interval '1 hour') s(d)
    
        date    | hour 
    ------------+------
     2018-01-24 |    1
     2018-01-24 |    2
     2018-01-24 |    3
     2018-01-24 |    4
    ...
    

    【讨论】:

    • 什么是“s(d)”部分?我不熟悉这种语法。那是在做什么?将其定义为一个名为“d”的系列?
    • 它是一个带有列名的别名。是的,它将生成的时间戳定义为d
    • 为什么是 s(d),而不仅仅是“AS d”?这只是你的风格?
    • s(d) 更正式。 s 就像一个表名,d 是一个列。因此你可以使用select s.d ... 但总的来说这是风格问题。
    • 这只给出最后一天的第 1 小时。
    【解决方案2】:

    使用cross join

    WITH hrs AS (
           SELECT gs.hr
           FROM generate_series(1,24) gs(hr)
          ),
          pricedate AS (
           SELECT gs.priceate
           FROM generate_series('2018-01-24', '2018-01-26', interval '1 day') gs(pricedate)
          )
    SELECT pricedate.pricedate, hrs.hr
    FROM hrs CROSS JOIN pricedate
    WHERE pricedate.pricedate BETWEEN '2018-01-24' AND '2018-01-26'
    ORDER BY pricedate.pricedate, hrs.hour
    

    【讨论】:

    • 不错。我认为您甚至不需要 where 子句。我忘记了交叉连接功能!这就是它的关键。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多