Postgres会自动将日期字段和时间戳字段转换为timestamptz
我有一个基于公用表表达式(CTE)的视图。
create or replace view viewname
as
WITH all_dates AS
(
SELECT generate_series
(
( SELECT min(date_trunc('day'::text, problem_time))::date AS min
FROM tablename)
, now()::date
, '1 day'::interval
)::date AS date_id
)
, ..... rest of view
命令执行时,Postgres生成的视图为
create or replace viewname
as
WITH all_dates AS
(
SELECT generate_series
(
(
( SELECT min(date_trunc('day'::text,problem_time))::date AS min
FROM tablename))::timestamp with time zone
, now()::date::timestamp with time zone
, '1 day'::interval)::date AS date_id
)
, ..... rest of view
在对带时间戳字段进行筛选并继续深入到CTE结构时,被比较的值被转换为timestamptz。
在我写的地方
where response >= reference
-- response is a timestamp type
-- reference is a timestamp type from some other preceding query
Postgres正在转换为
where response >= reference::timestamp with time zone
我的问题是,为什么会发生这种情况,以及如何防止它?
解决方案
转换之所以发生,是因为不存在函数 generate_series(date, date, interval)。因此你的列会被转换为函数能够接受的类型。Postgres已经在 TIMESTAMP WITH TIME ZONE 与 TIMESTAMP [WITHOUT TIME ZONE] 之间任意选取了 TIMESTAMP WITH TIME ZONE。
对于后者,没有看到完整的模式和查询,很难说清原因。很可能一个或多个列不是你预期的类型,因此一切都被提升为 TIMESTAMP WITH TIME ZONE,以便比较能够工作。
最后,没有理由在 TIMESTAMP 与 TIMESTAMP WITH TIME ZONE(aka timestamptz)之间取其一。PostgreSQL中这些类型的存储需求相同,你也不会在比较和转换时遇到怪异的边界情况。然而,请记住,所有比较都在客户端设置的时区内进行。因此,如果你的客户端设置为EDT,但另一位客户端在UTC下插入时间戳,那么你对该时间戳所表示的小时数或日期的理解将会不同。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。