Lấy cảm hứng từ nhận xét của @ Frank, tôi đã chạy một số thử nghiệm và điều chỉnh truy vấn của mình cho phù hợp. Điều này phải là 1) đúng và 2) càng nhanh càng tốt:
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;
Vì không có dấu thời gian trong tương lai trong bảng của bạn (tôi giả sử), bạn không cần giới hạn trên.
date_trunc('day', now())
gần giống với now()::date
(hoặc một số lựa chọn thay thế khác được nêu chi tiết bên dưới), chỉ là nó trả về timestamp
thay vì date
. Cả hai đều dẫn đến timestamp
dù sao sau khi thêm một khoảng interval
.
Các biểu thức dưới đây hoạt động hơi khác một chút. Chúng mang lại các kết quả khác nhau một cách tinh tế vì localtimestamp
trả về kiểu dữ liệu timestamp
while now()
trả về timestamp with time zone
. Nhưng khi truyền đến date
, hoặc được chuyển đổi thành cùng một địa phương ngày và timestamp [without time zone]
cũng được cho là ở múi giờ địa phương. Vì vậy, khi so sánh với timestamp with time zone
tất cả đều dẫn đến cùng một dấu thời gian UTC trong nội bộ. Thêm chi tiết về cách xử lý múi giờ trong câu hỏi liên quan này.
Tốt nhất trong số năm. Đã thử nghiệm với PostgreSQL 9.0. Lặp lại với 9.1.5:kết quả nhất quán trong khoảng sai số 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
rõ ràng là nhanh hơn một chút so với CURRENT_DATE
.