Generate_series 在 Postgres 中从 table 中的开始和结束日期

Generate_series in Postgres from start and end date in a table

我一直在尝试在时间戳字段中生成从第一个日期到最后一个日期的一系列日期 (YYYY-MM-DD HH)。我已经得到了我需要的 generate_series(),但是 运行 在尝试从 table 中获取开始和结束日期时遇到了问题。我有以下粗略的想法:

with date1 as
(
SELECT start_timestamp as first_date
FROM header_table
ORDER BY start_timestamp DESC
LIMIT 1
),
date2 as
(
SELECT start_timestamp as first_date
FROM header_table
ORDER BY start_timestamp ASC    
LIMIT 1
)
    select generate_series(date1.first_date, date2.first_date
                         , '1 hour'::interval)::timestamp as date_hour

from
(   select * from date1
    union
    select * from date2) as foo

Postgres 9.3

试试这个:

with dateRange as
  (
  SELECT min(start_timestamp) as first_date, max(start_timestamp) as last_date
  FROM header_table
  )
select 
    generate_series(first_date, last_date, '1 hour'::interval)::timestamp as date_hour
from dateRange

注意: 您想要 a 行中的 2 个日期,而不是单独的行。

see this sqlfiddle demo

改用聚合函数怎么样?

with dates as (
      SELECT min(start_timestamp) as first_date, max(start_timestamp) as last_date
      FROM header_table
     )
select generate_series(first_date, last_date, '1 hour'::interval)::timestamp as date_hour
from dates;

甚至:

select generate_series(min(start_timestamp),
                       max(start_timestamp),
                       '1 hour'::interval
                      )::timestamp as date_hour
from header_table;

你不需要 CTE,那会比必要的更昂贵。
并且您不需要强制转换为 timestamp,当您将 timestamp 类型提供给 [=24] 时,结果已经 是数据类型 timestamp =].详情在这里:

  • Generating time series between two dates in PostgreSQL

在 Postgres 9.3 或更高版本中,您可以使用 LATERAL 连接:

SELECT to_char(ts, 'YYYY-MM-DD HH24') AS formatted_ts
FROM  (
   SELECT min(start_timestamp) as first_date
        , max(start_timestamp) as last_date
   FROM   header_table
   ) h
  , generate_series(h.first_date, h.last_date, interval '1 hour') g(ts);

可选择 to_char() 以您提到的格式获得文本形式的结果。

这适用于 任何 Postgres 版本:

SELECT generate_series(min(start_timestamp)
                     , max(start_timestamp)
                     , interval '1 hour') AS ts
FROM   header_table;

通常会快一点。
SELECT 列表中调用 set-returning 函数是一个非标准的 SQL 特性,并且被一些人反对。此外,还有最终在 Postgres 10 中修复的行为异常(尽管不是针对这个简单的案例)。参见:

注意 NULL 处理的细微差别:

相当于

max(start_timestamp)

通过

获得
ORDER BY start_timestamp DESC <b>NULLS LAST</b>
LIMIT 1

没有 NULLS LAST NULL 值按降序排列在 前面 (如果 可以 是 [=21= 中的 NULL 值]). last_date 你会得到 NULL,你的查询会变成空的。

详情:

  • Why do NULL values come first when ordering DESC in a PostgreSQL query?