PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Seleziona solo i timestamp di oggi (da mezzanotte).

Ispirato dal commento di @Frank, ho eseguito alcuni test e adattato la mia query di conseguenza. Questo dovrebbe essere 1) corretto e 2) il più veloce possibile:

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;

Poiché non ci sono timestamp futuri nella tua tabella (presumo), non hai bisogno di un limite superiore.
date_trunc('day', now()) è quasi uguale a now()::date (o altre alternative descritte di seguito), solo che restituisce timestamp invece di una date . Entrambi danno come risultato un timestamp comunque dopo aver aggiunto un interval .

Le seguenti espressioni funzionano in modo leggermente diverso. Danno risultati leggermente diversi perché localtimestamp restituisce il tipo di dati timestamp mentre now() restituisce timestamp with time zone . Ma quando viene trasmesso a date , entrambi vengono convertiti nello stesso locale data e un timestamp [without time zone] si presume che sia anche nel fuso orario locale. Quindi, se confrontato con il corrispondente timestamp with time zone risultano tutti nello stesso timestamp UTC internamente. Maggiori dettagli sulla gestione del fuso orario in questa domanda correlata.

Al meglio dei cinque. Testato con PostgreSQL 9.0. Ripetuto con 9.1.5:risultati coerenti con un margine di errore dell'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 è ovviamente leggermente più veloce di CURRENT_DATE .