postgresql date datetime timestamp postgresql-8.4

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