Verwenden Sie now() oder CURRENT_TIMESTAMP für den Zweck.
Der Grund für das unterschiedliche Ergebnis Ihrer Abfragen ist folgender:
Wenn Sie zwei Werte vom Typ date
subtrahieren , ist das Ergebnis eine integer
und abs()
ist anwendbar.
Wenn Sie zwei Werte vom Typ timestamp
subtrahieren (oder nur einer ist ein timestamp
), ist das Ergebnis ein interval
, und abs()
ist nicht anwendbar. Sie könnten ihn durch CASE
ersetzen Ausdruck:
ORDER BY CASE WHEN expiry > now() THEN expiry - now() ELSE now() - expiry END
Oder Sie können extract()
die Unix epoch
aus dem resultierenden interval
wie @Craig bereits demonstriert hat. Ich zitiere:"für Intervallwerte die Gesamtzahl der Sekunden im Intervall". Dann können Sie abs()
verwenden nochmal:
ORDER BY abs(extract(epoch from (expiry - now())));
age()
würde dem Intervall einfach eine besser lesbare Darstellung hinzufügen, indem Tage zu Monaten und Jahren für größere Intervalle zusammengefasst werden. Aber das ist nebensächlich:Der Wert wird nur zum Sortieren verwendet.
Da Ihre Spalte vom Typ timestamp ist, sollten Sie CURRENT_TIMESTAMP
verwenden (oder now()
) anstelle von CURRENT_DATE
, oder Sie erhalten ungenaue Ergebnisse (oder sogar falsche für "heute").