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").