【问题标题】:Calculated time of day field in Postgres from timestamp根据时间戳计算 Postgres 中的时间字段
【发布时间】:2021-12-31 03:58:41
【问题描述】:

我有一个名为statdatetimestamp with time zone 字段,条目看起来像这样2021-11-17 12:47:54-08。我想创建一个仅在本地表达时间的字段,因此它看起来像12:47:54。 (此数据记录在 iPhone 上,时间为太平洋标准时间 12:28)。 (使用@AdrianKalver 的视图转到帖子底部以获取解决方案)

select *,statdate :: timestamp :: time as stattime  from table

在 PGAdmin 中工作,示例结果是 12:47:54 根据需要。我如何使它成为一个改变表

ALTER TABLE tablename add COLUMN stattime timestamp generated always AS (select *,statdate :: timestamp :: time as stattime from tablename) stored;

语法错误。

ALTER TABLE tablename add COLUMN stattime timestamp generated always AS ( EXTRACT(HOUR FROM statdate) || ':' ||  EXTRACT(MINUTE FROM statdate) || ':' ||  EXTRACT(SECOND FROM statdate)) stored;

ERROR: generation expression is not immutable 我认为这是一个类型问题,尽管 postgres 可以使用这种语法连接字符串和数字。

刚刚尝试了其他方法

ALTER TABLE tablename add COLUMN stattime timestamp generated always AS ( Cast(EXTRACT(HOUR FROM statdate) as text) || ':' ||  cast(EXTRACT(MINUTE FROM statdate) as text) || ':' ||  cast(EXTRACT(SECOND FROM statdate) as text) ) stored;  -- ERROR:  generation expression is not immutable

我在图表中使用小时和分钟,但无法进入 Chartkick 中间。可以在高图表中做到这一点,但认为创建视图图表并使用它会更简单。 Rails/Chartkick 看起来像

<%= line_chart TableName.where(statdate: start..current_date).pluck(:statdate, :y_axis) %>

并且无法将其分开。创建一个视图表也是如此。

这样做的正确方法是什么?我已经查看了这里和 postgresql 文档,但运气不佳。

按照cmets,解决办法

      CREATE OR REPLACE VIEW public.view_bp_with_time AS
  SELECT 
    id,
     statdate,
     statdate :: time AS stattime,
     y-axis
     FROM table_name
   ORDER BY statdate

现在引入 Rails。没有我想的那么简单。我下周不用电脑了。

【问题讨论】:

  • 看起来您正在尝试通过更改其列类型来 REPLACEVIEW。那是行不通的。在psql\d public.view_bp_with_time 返回什么?仅供参考,time with time zone 几乎没用,只需使用 time
  • 另外,如果statdatetimestamp with time zone,你所要做的就是statdate::time
  • 我猜是因为您正在对一个已经存在的视图执行 ... REPLACE VIEW public.view_bp_with_time 并且将 stattime 作为文本字段。 \d public.view_bp_with_time 应该告诉你。如果是这种情况,您将需要 DROP 视图并运行您的新 CREATE OR REPLACE VIEW public.view_bp_with_time ...
  • 不,不要DROP桌子,DROP视图。
  • 我的错,我错过了。应该只是 statdate :: time AS stattime 行,而不是 SELECT

标签: ruby-on-rails postgresql datetime concatenation generated-columns


【解决方案1】:

这里:

https://www.postgresql.org/docs/current/sql-createtable.html

生成总是作为 (generation_expr) 存储

此子句将列创建为生成列。该列不能写入,读取时会返回指定表达式的结果。

需要关键字 STORED 来表示该列将在写入时计算并将存储在磁盘上。

生成表达式可以引用表中的其他列,但不能引用其他生成的列。使用的任何函数和运算符都必须是不可变的。不允许引用其他表。

基本上,从timestamptztimestamp 的演员表不是一成不变的,因为涉及到时区。

欲了解更多信息,请参阅:

https://www.postgresql.org/docs/14/xfunc-volatility.html

要么:

  1. 创建一个执行转换的视图。

  2. 将它包含在您的查询中,就像您在 pgAdmin4 示例中显示的那样。

  3. 在表上创建一个timestamp 字段,然后将值添加到该字段作为INSERT\UPDATE 的一部分,或者添加一个触发器。

【讨论】:

  • 你是说我不能在创建列时填充它?将不得不审查意见,虽然我已经使用它们。在 OP 中添加了为什么我认为第 2 项不起作用。谢谢你的建议。
猜你喜欢
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 2019-01-15
  • 2019-06-10
  • 1970-01-01
相关资源
最近更新 更多