如何在水平行中显示特定日期范围内的所有日期?

Zak*_*ain 3 sql row time-series postgresql-9.1 generate-series

我在 PostgreSQL 中有一个数据库表,命名如下t1

姓名 开始日期 结束日期
10 月 18 日 2018-10-01 2018-10-05

我想要日期范围的结果,例如:

10 月 18 日 2018-10-01 2018-10-02 2018-10-03 2018-10-04 2018-10-05

在我的帮助下,generate_series()我可以“垂直”地做到这一点,但是如何在一行中获得结果?

Erw*_*ter 5

使用generate_series()。但 SQL 不允许结果列的数量是动态的。因此,您必须将结果包装在字符串、数组或文档类型中才能使其正常工作。子查询中的 ARRAY 构造函数的示例LATERAL- 在 Postgres 10 或更高版本中:

SELECT t1.name, d.date_arr::date[]
FROM   t1
LEFT   JOIN LATERAL (
   SELECT ARRAY(SELECT generate_series(t1.startdate::timestamp
                                     , t1.enddate::timestamp
                                     , interval '1 day'))
   ) d(date_arr) ON true;
Run Code Online (Sandbox Code Playgroud)

为什么(最好)Postgres 10 或更高版本?

为什么要演员timestamp

为什么LEFT JOIN .. ON true

尽管LEFT JOIN在这种特殊情况下没有必要(可能是CROSS JOIN),因为 ARRAY 构造函数总是返回一行。

Postgres 9.1

LATERAL需要 Postgres 9.3 或更高版本。您可以用相关子查询替换:

SELECT name
     , ARRAY(SELECT generate_series(startdate::timestamp
                                  , enddate::timestamp
                                  , interval '1 day')::date)
FROM   t1;
Run Code Online (Sandbox Code Playgroud)

甚至适用于 pg 8.4:

db<>在这里摆弄

但请考虑升级到当前版本。

crosstab()

crosstab()也无法克服 SQL 的静态特性。准备好的行类型的解决方法有限......


归档时间:

查看次数:

1125 次

最近记录:

2 年,3 月 前