sql - 使用 to_char 和日期在 postgres 中添加生成的列

标签 sql postgresql

我有一个日期栏 created_at在 postgres 表中。我有一个长时间运行的查询,按周对数据进行分组,因此查询的一部分是

(SELECT TO_CHAR(score.created_at, 'IYYY-IW') AS week, 
customer_id, AVG(score) AS avg_week_score FROM score

这是低效的,我想使用 Postgres 12 中新生成的列功能来存储每个插入日期的文本版本。

我试着跑
alter table score add column gen_week text generated always as (TO_CHAR(created_at, 'IYYY-IW')) stored;

但得到
ERROR:  generation expression is not immutable

我猜这与 created_at 依赖于语言环境,尤其是时区这一事实有关,所以我尝试了
alter table score add column week_gen text generated always as (TO_CHAR(created_at::timestamptz at time zone 'UTC', 'IYYY-IW')) stored;

使时区明确,但这会产生相同的错误。

有没有办法使 to_char 与日期对象保持不变,或者我是否必须基于 to_char 定义我自己的不可变函数?

最佳答案

问题是to_char()可以从语言环境中进行修改——函数要么是不可变的,要么不是不可变的。

您可以使用 extract() 做同样的事情:

alter table score add column gen_week text generated always as 
    ((extract(isoyear from created_at) * 100 + extract(week from created_at))::text ) stored;

实际上,上面没有把连字符放进去,所以:
alter table score add column gen_week text generated always as
    (extract(isoyear from created_at)::text || '-' || lpad(extract(week from created_at)::text, 2, '0')) stored;

Here是一个db<> fiddle 。

关于sql - 使用 to_char 和日期在 postgres 中添加生成的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60250336/

相关文章:

sql - 数据库-关系代数自然连接 2 个表包含 2 个相同的列名

php - 用 PHP 解释 SQL

python - 查询需要 30-40 秒(通过 ORM 和原始 SQL)。 200kk行

java - Spring-Boot 兼容内存数据库,支持字符串数组(String[])数据类型

postgresql - 如何语法检查 PostgreSQL 配置文件?

mysql - 创建索引后查询速度很快,但几分钟后查询速度变慢 MySQL

sql - 无法绑定(bind)多部分标识符

sql - 检查每个组的列中是否存在值

PostgreSQL - 更改默认权限....在表上选择...在所有模式中

mysql - 从数据透视表中获取不重复的数据