This should be 1) correct and 2) as fast as possible:
SELECT u.login, u.id, u.first_name
FROM pref_users u
WHERE u.login >= now()::date + interval '1h'
AND u.login > u.logout
ORDER BY u.login;
As there are no future timestamps in your table (I assume), you need no upper bound.
Some equivalent expressions:
SELECT localtimestamp::date + interval '1h'
, current_date + interval '1h'
, date_trunc('day', now()) + interval '1h'
, now()::date + interval '1h'
now()::date
used to perform slightly faster than CURRENT_DATE
in older versions, but that’s not true any more in modern Postgres. But either is still faster than LOCALTIMESTAMP
in Postgres 14 for some reason.
date_trunc('day', now()) + interval '1h'
slightly differs in that it returns timestamptz
. But it is coerced to timestamp
according to the timezone
setting of the current session in comparison to the timestamp
column login
, doing effectively the same.
See:
- Ignoring time zones altogether in Rails and PostgreSQL
To return rows for the previous day instead of returning nothing when issued between 00:00 and 01:00 local time, use instead:
WHERE u.login >= (LOCALTIMESTAMP - interval '1h')::date + interval '1h'