Вдъхновен от коментара на @Frank, проведох някои тестове и съответно адаптирах заявката си. Това трябва да е 1) правилно и 2) възможно най-бързо:
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;
Тъй като във вашата таблица няма бъдещи времеви печати (предполагам), нямате нужда от горна граница.date_trunc('day', now())
е почти същото като now()::date
(или някои други алтернативи, описани подробно по-долу), само че връща timestamp
вместо date
. И двете водят до timestamp
така или иначе след добавяне на interval
.
Изразите по-долу се представят малко по-различно. Те дават фино различни резултати, защото localtimestamp
връща тип данни timestamp
докато now()
връща timestamp with time zone
. Но когато се прехвърля към date
, всеки се преобразува в същия локален дата и timestamp [without time zone]
се предполага, че също е в местната часова зона. Така че в сравнение със съответния timestamp with time zone
всички те водят до едно и също UTC времево клеймо вътрешно. Повече подробности за обработката на часовата зона в този свързан въпрос.
Най-доброто от пет. Тестван с PostgreSQL 9.0. Повторено с 9.1.5:последователни резултати в рамките на 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
очевидно е малко по-бърз от CURRENT_DATE
.