数量来自计算时的 Postgres“间隔”语法

问题描述 投票:0回答:1

我是 posgresql 的新手,正在寻找解决办法。只是将其放在这里供任何寻找它的人作为一般参考,因为处理日期和类型总是很耗时。

我对

interval
有疑问。通常我按如下方式使用它

select '2024-01-12'::date + interval '1 day' NextDay;  -- = 2024-01-13 00:00:00.000

我需要进行计算以获得从日期中添加/减去的间隔时间。以下所有错误:

select 
      '2024-01-12'::date + interval ((8 - extract(isodow from date_trunc('year', now())::text || ' day') FirstMondayDate___GivesError_1 -- SQL Error [42601]: ERROR: syntax error at or near "("
    , '2024-01-12'::date + interval (8 - extract(isodow from date_trunc('year', now())::text || ' day' FirstMondayDate___GivesError_2 -- SQL Error [42601]: ERROR: syntax error at or near "-"
    , '2024-01-12'::date + interval '8 day' - interval extract(isodow from date_trunc('year', now())::text || ' day' FirstMondayDate___GivesError_3 -- SQL Error [42601]: ERROR: syntax error at or near "("
    , '2024-01-12'::date + interval '8 day' - interval (extract(isodow from date_trunc('year', now()))  FirstMondayDate___GivesError_4 -- SQL Error [42601]: ERROR: syntax error at or near "extract"
;

下面的代码片段有效,将返回当年 1 月 1 日的日期和当年第一个星期一的日期。这里的教训是

interval
是一种数据类型。 ‘*86400’是因为计算结果是整数秒,一天有 86400 秒。

select 
    date_trunc('year', now())::date DateFirstJanThisYear
    , case 
        when extract(isodow from date_trunc('year', now())::date) = 1 then date_trunc('year', now())
        when extract(isodow from date_trunc('year', now())::date) > 1 then date_trunc('year', now())::date + ((8 - extract(isodow from date_trunc('year', now())::date))*86400)::text::interval
    end::date DateFirstMondayThisYear
;

无论你是谁,如果你正在寻找这个,希望它能为你节省一些时间。

postgresql
1个回答
0
投票

从技术上来说,你可以这样做,但是你需要添加

"
双引号:db<>fiddle demo

select '2024-01-12'::date
+"interval"((extract(isodow from date_trunc('year', now())))::text||' days');

使用

::interval
演员可能会更方便一点:

select '2024-01-12'::date 
+((8 - extract(isodow from date_trunc('year', now())))::text||' day')::interval

或者将

'1 day'::interval
乘以产生
int
/
numeric
的表达式:

select '2024-01-12'::date 
+(8 - extract(isodow from date_trunc('year', now()))) * '1d'::interval

引用文档

time
timestamp
interval
接受可选精度值
p
,它指定秒字段中保留的小数位数。默认情况下,精度没有明确的限制。
p
的允许范围是从
0
6

这意味着当您执行

interval ()
时,Postgres 期望在这些括号中获得可选的精度值
p
。您可能已经预料到它会起作用,因为可以通过这种方式使用类型化常量。不幸的是,它仅适用于某些类型

也可以使用类似函数的语法指定类型强制:

typename ( 'string' )

但并非所有类型名称都可以这样使用;详情请参阅第 4.2.9 节

并且在第 4.2.9 节中你会发现一个明确的警告:

由于语法冲突,

interval
time
timestamp
仅当用双引号引起来时才能以这种方式使用。

句法冲突是

p
的事情。

© www.soinside.com 2019 - 2024. All rights reserved.