比较日期和秒数与时间戳

问题描述 投票:0回答:3

我有一个Postgres表,它将创建的时间戳记存储在created_date DATE列中,并在created_time INT列中存储自午夜以来的秒数。

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

在MySQL中,我会写:

SELECT * FROM MyCustomers
WHERE ADDTIME(created_date,SEC_TO_TIME(created_time)) > 'somedateliteral'

在PostgreSQL中看起来如何?

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

sql postgresql date-arithmetic
3个回答
1
投票

只需将两者加在一起:

created_date + created_time * interval '1 second' > ?

1
投票

您可以使用make_interval()将分钟变成一个间隔,然后可以将其添加到date列中以构造适当的timestamp

created_date + make_interval(secs => created_time)

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

© www.soinside.com 2019 - 2024. All rights reserved.