Zainspirowany komentarzem @Frank przeprowadziłem kilka testów i odpowiednio dostosowałem zapytanie. Powinno to być 1) poprawne i 2) tak szybko, jak to możliwe:
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;
Ponieważ w Twojej tabeli nie ma przyszłych znaczników czasu (zakładam), nie potrzebujesz górnej granicy.date_trunc('day', now())
jest prawie taki sam jak now()::date
(lub inne alternatywy wyszczególnione poniżej), tylko że zwraca timestamp
zamiast date
. Oba dają timestamp
mimo wszystko po dodaniu interval
.
Poniższe wyrażenia działają nieco inaczej. Dają nieco inne wyniki, ponieważ localtimestamp
zwraca typ danych timestamp
podczas gdy now()
zwraca timestamp with time zone
. Ale kiedy rzuca się na date
, albo jest konwertowany na ten sam lokalny data i timestamp [without time zone]
zakłada się, że również znajduje się w lokalnej strefie czasowej. Więc w porównaniu z odpowiednim timestamp with time zone
wszystkie dają wewnętrznie ten sam znacznik czasu UTC. Więcej szczegółów na temat obsługi stref czasowych w tym powiązanym pytaniu.
Najlepsza z pięciu. Testowane z PostgreSQL 9.0. Powtórzone z 9.1.5:spójne wyniki w granicach 1% marginesu błędu.
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
jest oczywiście nieco szybszy niż CURRENT_DATE
.