postgresql - Seleccione las marcas de tiempo de hoy(desde la medianoche) solamente
date datetime (5)
Tengo un servidor con PostgreSQL 8.4 que se reinicia cada noche a la 01:00 (no preguntar) y necesito obtener una lista de usuarios conectados (es decir, sus marcas de tiempo son u.login > u.logout
):
SELECT u.login, u.id, u.first_name
FROM pref_users u
WHERE u.login > u.logout and
u.login > now() - interval ''24 hour''
ORDER BY u.login;
login | id | first_name
----------------------------+----------------+-------------
2012-03-14 09:27:33.41645 | OK171511218029 | Alice
2012-03-14 09:51:46.387244 | OK448670789462 | Bob
2012-03-14 09:52:36.738625 | OK5088512947 | Sergej
Pero al comparar u.login > now()-interval ''24 hour''
también entrega a los usuarios antes de la última 01:00, lo cual es malo, esp. en las mañanas.
¿Hay alguna forma eficiente de obtener los inicios de sesión desde la última 01:00 sin hacer acrobacias de cadena con to_char()
?
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 el mismo que now()::date
(u otras alternativas detalladas a continuación), solo que devuelve la timestamp
de timestamp
lugar de una date
. Ambos resultados en una timestamp
todos modos después de agregar un interval
.
A continuación las expresiones se desempeñan de manera ligeramente diferente. Producen resultados sutilmente diferentes porque la timestamp
localtimestamp
devuelve la timestamp
tipo de datos, mientras que now()
devuelve la timestamp . Pero cuando se convierte a la date
, cualquiera de los dos se convierte a la misma fecha local , y se presume que una timestamp [without time zone]
encuentra en la zona horaria local. Por lo tanto, en comparación con la timestamp with time zone
correspondiente timestamp with time zone
, todos dan como resultado internamente la misma marca de hora UTC. Más detalles sobre el manejo de la zona horaria en esta pregunta relacionada .
Lo mejor de cinco. Probado con PostgreSQL 9.0. Repetido con 9.1.5: resultados consistentes dentro del 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
.
Una forma fácil de obtener solo marcas de tiempo para el día actual desde la 01:00 es filtrar con CURRENT_DATE + interval ''1 hour''
Entonces tu consulta debería verse así:
SELECT u.login, u.id, u.first_name
FROM pref_users u
WHERE u.login > u.logout AND
u.login > CURRENT_DATE + interval ''1 hour''
ORDER BY u.login;
Espero que ayude.
select * from termin where DATE(dateTimeField) >= CURRENT_DATE AND DATE(dateTimeField) < CURRENT_DATE + INTERVAL ''1 DAY''
Esto me funciona, selecciona TODAS las filas con la fecha de hoy.
select * from termin where DATE(dateTimeField) = ''2015-11-17''
¡Esto funciona bien para mi!
where
u.login > u.logout
and
date_trunc(''day'', u.login) = date_trunc(''day'', now())
and
date_trunc(''hour'', u.login) >= 1