sql >> Base de Datos >  >> RDS >> PostgreSQL

Seleccione solo las marcas de tiempo de hoy (desde la medianoche)

Inspirado por el comentario de @Frank, realicé algunas pruebas y adapté mi consulta en consecuencia. Esto debería ser 1) correcto y 2) lo más rápido posible:

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;

Como no hay marcas de tiempo futuras en su tabla (supongo), no necesita un límite superior.
date_trunc('day', now()) es casi lo mismo que now()::date (o algunas otras alternativas detalladas a continuación), solo que devuelve timestamp en lugar de una date . Ambos dan como resultado una timestamp de todos modos después de agregar un interval .

Las siguientes expresiones funcionan de forma ligeramente diferente. Producen resultados sutilmente diferentes porque localtimestamp devuelve el tipo de datos timestamp mientras now() devuelve timestamp with time zone . Pero cuando se envía a date , cualquiera de los dos se convierte al mismo local fecha y una timestamp [without time zone] se supone que también está en la zona horaria local. Entonces, cuando se compara con la correspondiente timestamp with time zone todos dan como resultado la misma marca de tiempo UTC internamente. Más detalles sobre el manejo de la zona horaria en esta pregunta relacionada.

Mejor de cinco. Probado con PostgreSQL 9.0. Repetido con 9.1.5:resultados consistentes con un margen de error del 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 es obviamente un poco más rápido que CURRENT_DATE .