Terinspirasi oleh komentar @ Frank, saya menjalankan beberapa tes dan menyesuaikan kueri saya. Ini harus 1) benar dan 2) secepat mungkin:
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;
Karena tidak ada cap waktu di masa mendatang di tabel Anda (saya berasumsi), Anda tidak memerlukan batas atas.date_trunc('day', now())
hampir sama dengan now()::date
(atau beberapa alternatif lain yang dirinci di bawah), hanya saja ia mengembalikan timestamp
bukannya date
. Keduanya menghasilkan timestamp
tetap setelah menambahkan interval
.
Ekspresi di bawah ini tampil sedikit berbeda. Mereka menghasilkan hasil yang agak berbeda karena localtimestamp
mengembalikan tipe data timestamp
sementara now()
mengembalikan timestamp with time zone
. Tetapi ketika dilemparkan ke date
, baik dikonversi ke lokal yang sama tanggal, dan timestamp [without time zone]
dianggap berada di zona waktu lokal juga. Jadi jika dibandingkan dengan timestamp with time zone
semuanya menghasilkan stempel waktu UTC yang sama secara internal. Detail lebih lanjut tentang penanganan zona waktu dalam pertanyaan terkait ini.
Terbaik dari lima. Diuji dengan PostgreSQL 9.0. Diulang dengan 9.1.5:hasil yang konsisten dalam 1% margin kesalahan.
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
jelas sedikit lebih cepat dari CURRENT_DATE
.