date
フィールドで私はこれを行うことができます:
ORDER BY ABS(expiry - CURRENT_DATE)
フィールドを使用timestamp
すると、次のエラーが発生します。
関数abs(interval)は存在しません
date
フィールドで私はこれを行うことができます:
ORDER BY ABS(expiry - CURRENT_DATE)
フィールドを使用timestamp
すると、次のエラーが発生します。
関数abs(interval)は存在しません
Use now() or CURRENT_TIMESTAMP for the purpose.
The reason for the different outcome of your queries is this:
When you subtract two values of type date
, the result is an integer
and abs()
is applicable.
When you subtract two values of type timestamp
(or just one is a timestamp
), the result is an interval
, and abs()
is not applicable. You could substitute with a CASE
expression:
ORDER BY CASE WHEN expiry > now() THEN expiry - now() ELSE now() - expiry END
Or you can extract()
the unix epoch
from the resulting interval
like @Craig already demonstrated. I quote: "for interval values, the total number of seconds in the interval". Then you can use abs()
again:
ORDER BY abs(extract(epoch from (expiry - now())));
age()
would just add a more human readable representation to the interval by summing up days into months and years for for bigger intervals. But that's beside the point: the value is only used for sorting.
As your column is of type timestamp, you should use CURRENT_TIMESTAMP
(or now()
) instead of CURRENT_DATE
, or you will get inaccurate results (or even incorrect for "today").
Compare with current_timestamp
SELECT the_timestamp > current_timestamp;
The age
function is probably what you want when comparing them:
SELECT age(the_timestamp);
eg:
regress=# SELECT age(TIMESTAMP '2012-01-01 00:00:00');
age
----------------
8 mons 17 days
(1 row)
If you want an absolute distance, use:
SELECT abs( extract(epoch from age(the_timestamp)) );
これは機能します(そして正しいソートを提供します):
ABS(EXTRACT(DAY FROM expiry - CURRENT_TIMESTAMP))
残念ながら、Erwin Brandstetterが指摘したように、ソートの粒度が1日に低下します。