Generating time series between two dates in PostgreSQL
我有一个这样的查询,它可以很好地在两个给定日期之间生成一系列日期:
1 2 3 | SELECT DATE '2004-03-07' + j - i AS AllDate FROM generate_series(0, EXTRACT(doy FROM DATE '2004-03-07')::INT - 1) AS i, generate_series(0, EXTRACT(doy FROM DATE '2004-08-16')::INT - 1) AS j |
它在
有更好的解决方案吗?
可以在不转换为int/from int的情况下完成(但改为转换为to/from timestamp)
1 2 3 4 5 6 | SELECT date_trunc('day', dd):: DATE FROM generate_series ( '2007-02-01'::TIMESTAMP , '2008-04-01'::TIMESTAMP , '1 day'::INTERVAL) dd ; |
这应该是最佳方式:
1 2 3 4 | SELECT DAY::DATE FROM generate_series(TIMESTAMP '2004-03-07' , TIMESTAMP '2004-08-16' , INTERVAL '1 day') AS t(DAY); |
不需要额外的
date_trunc() 。对date (day::date )的强制转换是含蓄的。但也没有必要将日期文本作为输入参数强制转换到
date 中。相反,江户十一〔四〕是最好的选择。在性能上的优势很小,但没有理由不接受它。而且,您不必涉及DST(夏令时)规则以及从date 到timestamp with time zone 和后面的转换。见下文。
等效短语法:
1 2 | SELECT DAY::DATE FROM generate_series(TIMESTAMP '2004-03-07', '2004-08-16', '1 day') DAY; |
或者使用
1 | SELECT generate_series(TIMESTAMP '2004-03-07', '2004-08-16', '1 day')::DATE AS DAY; |
最后一个变量中需要
- select子句中多个返回函数的集合的预期行为是什么?
为什么?
1
2
3
4 SELECT oid::regprocedure AS function_signature
, prorettype::regtype AS return_type
FROM pg_proc
WHERE proname = 'generate_series';
1
2
3
4
5
6
7
8
9
10 function_signature | return_type
:-------------------------------------------------------------------------------- | :--------------------------
generate_series(INTEGER,INTEGER,INTEGER) | INTEGER
generate_series(INTEGER,INTEGER) | INTEGER
generate_series(BIGINT,BIGINT,BIGINT) | BIGINT
generate_series(BIGINT,BIGINT) | BIGINT
generate_series(NUMERIC,NUMERIC,NUMERIC) | NUMERIC
generate_series(NUMERIC,NUMERIC) | NUMERIC
generate_series(TIMESTAMP WITHOUT TIME zone,TIMESTAMP WITHOUT TIME zone,INTERVAL) | TIMESTAMP WITHOUT TIME zone
generate_series(TIMESTAMP WITH TIME zone,TIMESTAMP WITH TIME zone,INTERVAL) | TIMESTAMP WITH TIME zone
(
如您所见,不存在接受或返回
btw,
由于函数类型解析,我们仍然可以通过
Run through all candidates and keep those that accept preferred types
(of the input data type's type category) at the most positions where
type conversion will be required. Keep all candidates if none accept
preferred types. If only one candidate remains, use it; else continue
to the next step.
除了函数类型解析中的额外工作之外,这还为
- 如何在PostgreSQL中生成日期序列?
- 如何在PostgreSQL中生成时间序列?
我在小提琴上增加了演示,展示了更昂贵的查询计划:
此处
相关:
- 有没有办法在Postgres中禁用函数重载
- 生成一系列日期-使用日期类型作为输入
- Postgres数据类型转换
可以直接用日期生成序列。无需使用ints或时间戳:
1 2 3 4 5 6 | SELECT DATE::DATE FROM generate_series( '2004-03-07'::DATE, '2004-08-16'::DATE, '1 day'::INTERVAL ) DATE; |
你可以用like
选择Generate_series("2012-12-31"::timestamp,"2018-10-31"::timestamp,"1 day"::interval)::date