Inspirado pelo comentário de @Frank, fiz alguns testes e adaptei minha consulta de acordo. Isso deve ser 1) correto e 2) o mais rápido possível:
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;
Como não há timestamps futuros em sua tabela (suponho), você não precisa de limite superior.
date_trunc('day', now())
é quase o mesmo que now()::date
(ou algumas outras alternativas detalhadas abaixo), apenas que retorna timestamp
em vez de uma date
. Ambos resultam em um timestamp
de qualquer forma depois de adicionar um interval
. As expressões abaixo têm um desempenho ligeiramente diferente. Eles produzem resultados sutilmente diferentes porque
localtimestamp
retorna o tipo de dados timestamp
enquanto now()
retorna timestamp with time zone
. Mas quando convertido para date
, ambos são convertidos para o mesmo local data e um timestamp [without time zone]
presume-se que também esteja no fuso horário local. Então, quando comparado ao timestamp with time zone
correspondente todos eles resultam no mesmo timestamp UTC internamente. Mais detalhes sobre o tratamento de fuso horário nesta pergunta relacionada. Melhor de cinco. Testado com PostgreSQL 9.0. Repetido com 9.1.5:resultados consistentes com margem de erro de 1%.
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
é obviamente um pouco mais rápido que CURRENT_DATE
.