Inspireret af @Franks kommentar kørte jeg nogle tests og tilpassede min forespørgsel i overensstemmelse hermed. Dette skal være 1) korrekt og 2) så hurtigt som muligt:
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 der ikke er nogen fremtidige tidsstempler i din tabel (antager jeg), behøver du ingen øvre grænse.date_trunc('day', now())
er næsten det samme som now()::date
(eller nogle andre alternativer beskrevet nedenfor), kun at det returnerer timestamp
i stedet for en date
. Begge resulterer i et timestamp
alligevel efter tilføjelse af et interval
.
Nedenstående udtryk fungerer lidt anderledes. De giver subtilt forskellige resultater, fordi localtimestamp
returnerer datatypen timestamp
mens now()
returnerer timestamp with time zone
. Men når castet til date
, enten konverteres til det samme lokale dato og et timestamp [without time zone]
formodes også at være i den lokale tidszone. Så sammenlignet med det tilsvarende timestamp with time zone
de resulterer alle i det samme UTC-tidsstempel internt. Flere detaljer om tidszonehåndtering i dette relaterede spørgsmål.
Bedst af fem. Testet med PostgreSQL 9.0. Gentaget med 9.1.5:ensartede resultater inden for 1 % fejlmargen.
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
er åbenbart lidt hurtigere end CURRENT_DATE
.