Inspirerad av @Franks kommentar körde jag några tester och anpassade min fråga efter det. Detta ska vara 1) korrekt och 2) så snabbt som möjligt:
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;
Eftersom det inte finns några framtida tidsstämplar i din tabell (förmodar jag), behöver du ingen övre gräns.date_trunc('day', now())
är nästan samma som now()::date
(eller några andra alternativ som beskrivs nedan), bara att den returnerar timestamp
istället för ett date
. Båda resulterar i en timestamp
i alla fall efter att ha lagt till ett interval
.
Nedanstående uttryck fungerar något annorlunda. De ger subtilt olika resultat eftersom localtimestamp
returnerar datatypen timestamp
medan now()
returnerar timestamp with time zone
. Men när cast till date
, antingen konverteras till samma lokala datum och en timestamp [without time zone]
antas också vara i den lokala tidszonen. Så jämfört med motsvarande timestamp with time zone
de resulterar alla i samma UTC-tidsstämpel internt. Mer information om tidszonshantering i den här relaterade frågan.
Bäst av fem. Testad med PostgreSQL 9.0. Upprepad med 9.1.5:konsekventa resultat inom 1 % felmarginal.
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
är uppenbarligen något snabbare än CURRENT_DATE
.