将日期和秒与时间戳进行比较

2vuwiymt  于 2021-08-13  发布在  Java
关注(0)|答案(3)|浏览(394)

我有一个postgres表,它将创建的时间戳存储在 created_date DATE 列和a created_time INT 从午夜开始保持秒数的列。
编辑:该表位于客户的生产数据库中,并存储来自旧系统的数据,因此不可能更改模式。
我想根据创建的时间戳进行选择。
在mysql中,我会写道:

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

在postgresql中会是什么样子?
我可以在手册中看到示例,但它们都使用文本值,而不是表列中的值。

zvms9eto

zvms9eto1#

在坚持你的设计的同时

假设iso格式 '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'` 从文本中获取相应的日期/时间部分(如果没有时间段,后者会中断,而前者显然也会使用日期文字。)

#### 为什么?

使之成为“萨尔盖布”。请参见:
“sargable”这个词到底是什么意思?
与动态计算时间戳的解决方案相反¹, 此查询可以使用基本的多列索引:

CREATE INDEX multicolumn_created ON mycustomers (created_date, created_time);

(¹ 您可以创建一个匹配的表达式索引以使其工作……)
postgres可以通过行值比较很好地利用这个索引(上次我查看时,mysql无法做到这一点。)请看:
“where(col1,col2)<(val1,val2)”的sql语法术语
大表上带偏移量的查询优化

### 适当的修理

将时间戳存储为 `date` +  `integer` 通常是一个没有好处的设计错误。使用 `timestamp` 相反。您可能需要切换到一般首选的 `timestamptz` 在做的时候。请参见:
在rails和postgresql中完全忽略时区
其他答案已经提供了要转换的表达式 `(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<>在这里摆弄
7lrncoxx

7lrncoxx2#

把两者加起来:

created_date + created_time * interval '1 second' > ?
ql3eal8s

ql3eal8s3#

你可以用 make_interval() 把秒变成一个间隔,这个间隔又可以加到 date 构造适当的 timestamp :

created_date + make_interval(secs => created_time)

相关问题