【问题标题】:SQL: Add UTC timestamp column to table from date and timeSQL:从日期和时间将 UTC 时间戳列添加到表中
【发布时间】:2016-08-13 15:48:10
【问题描述】:

我在 Postgres 中有一个包含日期列和时间列的表。我想添加一个新列,该列具有基于日期和时间列的 utc(或时间戳)值。

我尝试了以下方法:

INSERT INTO mytable (utc) SELECT EXTRACT(EPOCH FROM (date || ' ' || time )::timestamp);

但我得到了错误:

ERROR: column "date" does not exist
SQL state: 42703
Hint: There is a column named "date" in table "mytable", but it cannot be referenced from this part of the query.

而且肯定有日期和时间列。

有谁知道如何根据日期和时间列向 UTC 列添加值?
例如:09/21/2012 12:56:00 应该变成类似 411730.830555

我正在尝试做类似于this question 的事情(我认为)。

【问题讨论】:

  • insert 可以插入新的。使用alter table add column 添加新列。但总的来说,存储可以轻松(且廉价地)从已经存在的数据中派生的数据是一个坏主意。创建包含该列的视图,无需重复信息。为什么要将日期和时间存储在两列中?为什么不使用单个 timestamp 列?
  • 这正是我想要做的。我无法为每一行手动创建 UTC 日期时间值。但是我碰巧有一个已经创建的具有日期和时间值的表。要使用单个 UTC 列,我需要能够根据现有值创建这些值。
  • 此外,根据具体情况,使用多个列来解释数据的不同部分或以不同的方式读取会很有帮助。在此示例中,看到 411730.830555 之类的 UTC 日期对人类来说可能毫无意义,但它是功能所必需的,因此最好同时拥有日期和时间列。
  • 不,冗余存储数据没有“有用”。如果您需要以不同格式显示时间戳列,请创建一个执行此操作的视图。不要多次存储相同的信息。
  • 我仍然不清楚您要做什么。 alter 表有一个新的timestamp 列? extract(epoch...) 确实返回时间戳值,它返回一个整数值。 timestamp 完全不同:postgresql.org/docs/current/static/datatype-datetime.html

标签: sql postgresql utc


【解决方案1】:

你想做什么

添加一个新的你需要一个alter table声明:

alter table mytable add column utc float;

然后您需要使用新数据更新该列:

update mytable
  set utc = EXTRACT(EPOCH FROM (date || ' ' || time )::timestamp);

您现在需要一个使日期/时间和 utc 列保持同步的触发器。

你应该怎么做

以上不是一个好主意。关系数据库中的经验法则:

切勿存储可以从数据库中已有数据中派生的信息。

因此,干净的解决方案是不要将日期和时间存储在两个不同的列中,也不要添加另一列以不同的表示形式包含完全相同的信息。

您应该有一个类型为 timestamp 的列,然后创建一个视图以返回您想要的不同格式的 timestamp

-- add the new timestamp column
alter table mytable add column ts_column timestamp;

-- copy the data 
update mytable
  set ts_column = (date || ' ' || time )::timestamp;

-- get rid of the old columns
alter table mytable 
     drop column date, 
     drop column time;

-- now create a view that display the information in different ways              
create view formatted_mytable
as
select id, 
       ts_column, 
       to_char(ts_column, 'yyyy-mm-dd') as date_only, 
       to_char(ts_column, 'hh24:mi:ss') as time_only, 
       extract(epoch from ts_column) as epoch
from my_table;

这样您就不需要复制存储在表格中的信息,因为您需要不同的显示格式。

【讨论】:

  • 有效的方法发生了变化:INSERT INTO mytable (utc) SELECTset utc =
【解决方案2】:

在进一步调查后,其他答案的格式实际上与我想要的不同。

我提到所需的格式是ddddd.tttttt,其中d 是日期的数字版本(特别是自1900-01-00 以来的天数),t 是24 小时的一小部分。这是 Excel 用于存储日期时间值的格式,称为“串行日期时间”。欲了解更多信息,请参阅Dates and Times in Excel.

我认为这类似于 postgresql 的时间戳格式,但事实证明它不适用于我的目的。

这是有效的:

UPDATE mytable SET utc = DATE_PART('day', '2012-09-21'::timestamp - '1899-12-30'::timestamp) + (EXTRACT( HOURS FROM time::time)/24) + (EXTRACT( MINUTES FROM time::time)/1440) + (EXTRACT( SECONDS FROM time::time)/86400);

只是想更新答案以确保准确性,以防其他人偶然发现此问题。互联网上似乎很少有关于如何做到这一点的信息。感谢@a_horse_with_no_name 的回答;这确实在某些方面帮助了我。

【讨论】:

  • 再次:不要那样做。存储一个常规的timestamp 并在显示 时将其格式化为您想要的任何格式。存储冗余信息是个坏主意
猜你喜欢
  • 2023-03-31
  • 2012-01-30
  • 2011-09-02
  • 2021-12-03
  • 1970-01-01
  • 2015-04-14
  • 2018-08-21
相关资源
最近更新 更多