Inspiriert von @Franks Kommentar habe ich einige Tests durchgeführt und meine Abfrage entsprechend angepasst. Dies sollte 1) richtig und 2) so schnell wie möglich sein:
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;
Da Ihre Tabelle keine zukünftigen Zeitstempel enthält (nehme ich an), brauchen Sie keine Obergrenze.date_trunc('day', now())
ist fast dasselbe wie now()::date
(oder einige andere unten beschriebene Alternativen), nur dass es timestamp
zurückgibt anstelle eines date
. Beides ergibt einen timestamp
trotzdem nach Hinzufügen eines interval
.
Die folgenden Ausdrücke verhalten sich etwas anders. Sie liefern subtil unterschiedliche Ergebnisse, weil localtimestamp
gibt den Datentyp timestamp
zurück während now()
gibt timestamp with time zone
zurück . Aber wenn es auf date
gecastet wird , wird entweder in dasselbe local konvertiert Datum und einen timestamp [without time zone]
wird ebenfalls in der lokalen Zeitzone vermutet. Also im Vergleich zum entsprechenden timestamp with time zone
sie alle führen intern zu demselben UTC-Zeitstempel. Weitere Einzelheiten zur Behandlung von Zeitzonen in dieser verwandten Frage.
Das Beste von fünf. Getestet mit PostgreSQL 9.0. Wiederholt mit 9.1.5:konsistente Ergebnisse innerhalb einer Fehlerspanne von 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
ist offensichtlich etwas schneller als CURRENT_DATE
.