我是 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
;
无论你是谁,如果你正在寻找这个,希望它能为你节省一些时间。
从技术上来说,你可以这样做,但是你需要添加
"
双引号: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
的事情。