PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wählen Sie nur die Zeitstempel von heute (seit Mitternacht) aus

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 .