我为postgres提供了以下过程,该过程将用于为不同表的分区生成名称.

CREATE OR REPLACE FUNCTION get_partition_name(table_name VARCHAR, archived_on TIMESTAMP)
RETURNS VARCHAR
AS $get_partition_name$
DECLARE
    partition_date TIMESTAMP := date_trunc('month', archived_on, 'Universal');
BEGIN

    RETURN CONCAT(table_name, to_char(partition_date, '"_y"YYYY"m"MM'));
    
END;
$get_partition_name$ LANGUAGE plpgsql;

当我运行这个函数时,我得到了正确的格式化字符串,但是月份是关闭的:

SELECT get_partition_name('george', '2024-03-06 12:39:48.399 -0500');
RESULT: george_y2024m02

为什么要取消一个月?即使当您手动将其从东部标准时间转换为UTC时,它也不会带您回到那么远的地方.当我从声明中删除UTC参数时,似乎工作正常?

SELECT get_partition_name('george', '2024-03-06 12:39:48.399 -0500');
RESULT: george_y2024m03

我到底做错了什么?

推荐答案

对于文档date_trunc:

当输入值的类型为TIMESTAMP WITH TIME ZONE时,将针对特定时区执行截断;例如,截断到DAY将生成该时区的午夜时值.默认情况下,截断是相对于当前时区设置进行的,但可以提供可选的TIME_ZONE参数来指定不同的时区.可以按照第8.5.3节中描述的任何方式指定时区名称.

show timezone;
 TimeZone 
----------
 EST

select date_trunc('month', '2024-03-06 12:39:48.399 -0500'::timestamptz);
       date_trunc       
------------------------
 2024-03-01 00:00:00-05

select date_trunc('month', '2024-03-06 12:39:48.399 -0500'::timestamptz, 'UTC');
       date_trunc       
------------------------
 2024-02-29 19:00:00-05

第一种情况使用ESTtimezone,并处理时间戳,因为它在时区中.这意味着截断到每月第一天的午夜.

第二种情况是在UTC中将日期截断为月,值为2024-03-01 00:00:00,并将其旋转到ESTtimezone.

本质上:

select ('2024-03-01 00:00:00+00' at time zone 'EST')::timestamptz ;
        timezone        
------------------------
 2024-02-29 19:00:00-05

Sql相关问答推荐

从列的不同值创建列

前面的语句不喜欢AND LIKE?当try 更新使用ID和日期过滤的表时

有没有办法用SQL编写一条CASE语句,如果列A&>0,那么列B,列C=0

在Postgres中实现合并功能的干净方法,因为当目标/源不匹配时

使用占位符向SQL INSERT查询添加 case

如何在不更改S代码的情况下,判断存储过程调用了多少次clr函数?

PostgreSQL中的合并命令是原子的,还是需要一些类似于SQL Server版本的内容?

当一个视图在Postgres中失效时?

在SQL中返回缺省值,即使查询不返回任何结果

Select 列组(按同一表格中的另一列分组)Laravel 10

从结果SQL查询中排除空值

仅在日期相隔时递增(Oracle SQL)

无法访问级联删除导致的触发器中已删除的外键记录

不存在记录的国外关键点

如何使用SQL生成数据的滚动3天总和

其中使用表名作为;行值;记录?

如何 for each id创建长度等于id长度的不同日期序列?

使用对 nvarchar 列的多个 LIKE 操作优化 SQL 查询

SQL Server Where 条件

SQL:获取连接表的第一个项目