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

Sélectionnez uniquement les horodatages d'aujourd'hui (depuis minuit)

Inspiré par le commentaire de @ Frank, j'ai effectué quelques tests et adapté ma requête en conséquence. Cela doit être 1) correct et 2) aussi rapide que possible :

SELECT u.login, u.id, u.first_name
FROM   pref_users u
WHERE  u.login > u.logout
AND    u.login >= now()::date + interval '1h'
ORDER  BY u.login;

Comme il n'y a pas d'horodatage futur dans votre table (je suppose), vous n'avez pas besoin de limite supérieure.
date_trunc('day', now()) est presque identique à now()::date (ou d'autres alternatives détaillées ci-dessous), seulement qu'il renvoie timestamp au lieu d'une date . Les deux entraînent un timestamp de toute façon après avoir ajouté un interval .

Les expressions ci-dessous fonctionnent légèrement différemment. Ils donnent des résultats subtilement différents car localtimestamp renvoie le type de données timestamp tandis que now() renvoie timestamp with time zone . Mais lorsqu'il est converti en date , soit est converti dans le même local date, et un timestamp [without time zone] est également supposé être dans le fuseau horaire local. Ainsi, par rapport au timestamp with time zone correspondant ils aboutissent tous au même horodatage UTC en interne. Plus de détails sur la gestion des fuseaux horaires dans cette question connexe.

Le meilleur des cinq. Testé avec PostgreSQL 9.0. Répété avec 9.1.5 :résultats cohérents avec une marge d'erreur de 1 %.

SELECT localtimestamp::date     + interval '1h'  -- Total runtime: 351.688 ms
     , current_date             + interval '1h'  -- Total runtime: 338.975 ms
     , date_trunc('day', now()) + interval '1h'  -- Total runtime: 333.032 ms
     , now()::date              + interval '1h'  -- Total runtime: 278.269 ms
FROM   generate_series (1, 100000)

now()::date est évidemment légèrement plus rapide que CURRENT_DATE .