Inspirován komentářem @Franka jsem provedl několik testů a podle toho upravil svůj dotaz. To by mělo být 1) správné a 2) co nejrychlejší:
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;
Protože ve vaší tabulce nejsou žádná budoucí časová razítka (předpokládám), nepotřebujete žádnou horní hranici.date_trunc('day', now())
je téměř stejný jako now()::date
(nebo některé další alternativy popsané níže), pouze vrátí timestamp
místo date
. Výsledkem obou je timestamp
každopádně po přidání interval
.
Níže uvedené výrazy fungují mírně odlišně. Přinášejí mírně odlišné výsledky, protože localtimestamp
vrátí datový typ timestamp
zatímco now()
vrátí timestamp with time zone
. Ale při odeslání na date
, buď se převede na stejné místní datum a timestamp [without time zone]
předpokládá se, že je také v místním časovém pásmu. Tedy ve srovnání s odpovídajícím timestamp with time zone
všechny mají interně za následek stejné časové razítko UTC. Další podrobnosti o zpracování časového pásma v této související otázce.
Nejlepší z pěti. Testováno s PostgreSQL 9.0. Opakováno s 9.1.5:konzistentní výsledky v rozsahu 1 % chyb.
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
je samozřejmě o něco rychlejší než CURRENT_DATE
.