比较日期和秒与时间戳

时间:2020-05-27 19:51:29

标签: sql postgresql date-arithmetic

我有一个Postgres表,该表将创建的时间戳存储在library(stringi) stri_replace_all_regex(names(df1), pattern = paste0(as.character(df2$Partial_Match),"\\."), replacement = paste0(as.character(df2$Name),"\\."), vectorize_all = FALSE) #[1] "Bob.length" "Alex.length" "Gary.length" "Taylor.length" "Tom.length" "John.length" "Pat.length" #[8] "Mary.length" 列和一个created_date DATE列中,该列保存自午夜以来的秒数。

编辑:该表位于客户的生产db上,并且存储来自较旧系统的数据,无法进行模式更改。

我想根据创建的时间戳进行选择。

在MySQL中,我会写:

created_time INT

在PostgreSQL中看起来如何?

我可以在手册中看到示例,但是它们都使用文字值,而不是表列中的值。

3 个答案:

答案 0 :(得分:2)

您可以使用make_interval()将秒数转换为间隔,然后可以将其添加到date列中以构造适当的timestamp

created_date + make_interval(secs => created_time)

答案 1 :(得分:1)

只需将两者加在一起:

created_date + created_time * interval '1 second' > ?

答案 2 :(得分:0)

在坚持设计的同时

假设ISO format'somedateliteral'
由于它应该是时间戳文字,因此我将其命名为'timestamp_literal'

SELECT *, created_date + make_interval(secs => created_time) AS created_at
FROM   mycustomers
WHERE  (created_date, created_time)
     > (date 'timestamp_literal', EXTRACT(epoch FROM time 'timestamp_literal')::int);

date 'timestamp_literal'time 'timestamp_literal'从文字中获取相应的日期/时间部分。 (显然,如果没有时间部分,后者会中断,而显然,前者也可以使用日期文字)。

为什么?

使其“可燃”。参见:

与动态计算时间戳¹的解决方案相反,此查询可以使用基本的multicolumn index

CREATE INDEX multicolumn_created ON mycustomers (created_date, created_time);

(¹您可以创建一个匹配的表达式索引以使其起作用...)

Postgres可以通过 ROW值比较充分利用此索引。 (我上次看,MySQL无法做到这一点。)请参阅:

正确修复

将时间戳记存储为date + integer通常是没有好处的设计错误。请改用timestamp。您可能需要切换到通常首选的timestamptz。参见:

其他答案已经提供了将(date, integer)转换为timestamp的表达式-您可以使用它来修复表格:

BEGIN;

-- drop all depending objects: indexes, views, ...

ALTER TABLE mycustomers
   ALTER created_date TYPE timestamp
      USING (created_date + make_interval(secs => created_time)) 
 , DROP COLUMN created_time;

ALTER TABLE mycustomers RENAME created_date TO created_at;  -- or whatever

-- recreate all depending objects: indexes, views, ...

COMMIT;

采用这些列显然可以采用所有查询。眼前的查询变成:

SELECT * FROM mycustomers WHERE created_at > 'somedateliteral';

db <>提琴here