8

有了一个date字段,我可以做到这一点

ORDER BY ABS(expiry - CURRENT_DATE)

使用一个timestamp字段,我收到以下错误:

函数 abs(interval) 不存在

4

3 回答 3

13

为此目的使用now() 或 CURRENT_TIMESTAMP

您的查询结果不同的原因是:

当您减去 type 的两个值时date,结果为 aninteger并且abs()适用。
当您减去两个类型的值timestamp(或只有一个是 a timestamp)时,结果是 a interval,并且abs()不适用。你可以用一个CASE表达式代替:

ORDER BY CASE WHEN expiry > now() THEN expiry - now() ELSE now() - expiry END

或者你可以像@Craig 已经展示的那样从结果中提取extract()unix 。我引用:“对于间隔值,间隔中的总秒数”。然后你可以再次使用:epochintervalabs()

ORDER BY abs(extract(epoch from (expiry - now())));

age()通过将天数总结为月和年以获得更大的间隔,只会为间隔添加更人类可读的表示。但这不是重点:该值仅用于排序。

由于您的列是时间戳类型,您应该使用CURRENT_TIMESTAMP(or now()) 而不是 CURRENT_DATE,否则您将得到不准确的结果(甚至“今天”不正确)。

于 2012-09-17T13:58:45.800 回答
1

与之比较current_timestamp

SELECT the_timestamp > current_timestamp;

比较它们时,该age功能可能是您想要的:

SELECT age(the_timestamp);

例如:

regress=# SELECT age(TIMESTAMP '2012-01-01 00:00:00');
      age       
----------------
 8 mons 17 days
(1 row)

如果您想要绝对距离,请使用:

SELECT abs( extract(epoch from age(the_timestamp)) );
于 2012-09-17T13:58:11.340 回答
1

这有效(并给出正确的排序):

ABS(EXTRACT(DAY FROM expiry - CURRENT_TIMESTAMP))

不幸的是,正如 Erwin Brandstetter 所指出的,它将排序的粒度降低到一整天。

于 2012-09-17T14:06:34.273 回答