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 .