PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Trier les horodatages (y compris le futur) par distance absolue à partir de maintenant

Utilisez now() ou CURRENT_TIMESTAMP dans le but.

La raison du résultat différent de vos requêtes est la suivante :

Lorsque vous soustrayez deux valeurs de type date , le résultat est un integer et abs() est applicable.
Lorsque vous soustrayez deux valeurs de type timestamp (ou un seul est un timestamp ), le résultat est un interval , et abs() n'est pas applicable. Vous pouvez remplacer par un CASE expression :

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

Ou vous pouvez extract() l'epoch unix à partir de l'interval résultant comme @Craig l'a déjà démontré. Je cite :"pour les valeurs d'intervalle, le nombre total de secondes dans l'intervalle". Ensuite, vous pouvez utiliser abs() encore :

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

age() ajouterait simplement une représentation plus lisible par l'homme à l'intervalle en additionnant les jours en mois et en années pour des intervalles plus grands. Mais là n'est pas la question :la valeur n'est utilisée que pour le tri.

Comme votre colonne est de type timestamp, vous devez utiliser CURRENT_TIMESTAMP (ou now() ) au lieu de CURRENT_DATE , ou vous obtiendrez des résultats inexacts (ou même incorrects pour "aujourd'hui").