我在PostgreSQL中有一个名为t1
的数据库表,例如:
| Name | | StartDate | | EndDate |
----------------------------------------
| Oct-18 | | 2018-10-01| | 2018-10-05|
我想要日期范围的结果,例如:
| Oct-18 | |2018-10-01| |2018-10-02| |2018-10-03| |2018-10-04| |2018-10-05|
在generate_series()
的帮助下,我可以“垂直”地进行操作,但是如何在单行中获得结果?
答案 0 :(得分:2)
使用generate_series()
。但是SQL不允许动态数量的结果列。因此,您必须将结果包装在字符串,数组或文档类型中以使其起作用。
在LATERAL
子查询中使用ARRAY构造函数的示例-在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;
为什么(最好是)Postgres 10或更高版本?
为什么要强制转换为timestamp
?
为什么要LEFT JOIN .. ON true
?
LATERAL
需要Postgres 9.3或更高版本。您可以用相关的子查询代替:
SELECT name
, ARRAY(SELECT generate_series(startdate::timestamp
, enddate::timestamp
, interval '1 day')::date)
FROM t1;
即使与pg 8.4兼容:
db <>提琴here
但是请考虑升级到当前版本。
crosstab()
? crosstab()
也无法克服SQL的静态特性。准备好的行类型的解决方法很有限...