Consulta Postgresql entre intervalos de fechas


Estoy tratando de consultar mi base de datos postgresql para devolver resultados donde una fecha está en cierto mes y año. En otras palabras, me gustaría todos los valores para un mes-año.

La única forma en que he podido hacerlo hasta ahora es así:

SELECT user_id 
FROM user_logs 
WHERE login_date BETWEEN '2014-02-01' AND '2014-02-28'

El problema con esto es que tengo que calcular la primera fecha y la última fecha antes de consultar la tabla. ¿Hay una forma más sencilla de hacer esto?

Gracias

Author: Ana María Martínez Gómez, 2014-04-28

4 answers

Con fechas (y horas) muchas cosas se vuelven más simples si usas >= start AND < end.

Por ejemplo:

SELECT
  user_id
FROM
  user_logs
WHERE
      login_date >= '2014-02-01'
  AND login_date <  '2014-03-01'

En este caso, todavía necesita calcular la fecha de inicio del mes que necesita, pero eso debe ser sencillo en cualquier número de maneras.

La fecha de finalización también se simplifica; simplemente agregue exactamente un mes. No jugar con 28, 30, 31, etc.


Esta estructura también tiene la ventaja de poder mantener el uso de índices.


Muchas personas pueden sugerir una forma como la siguiente, pero no utilizar índices:

WHERE
      DATEPART('year',  login_date) = 2014
  AND DATEPART('month', login_date) = 2

Esto implica calcular las condiciones para cada fila de la tabla (un escaneo) y no usar index para encontrar el rango de filas que coincidirán (un búsqueda de rango).

 114
Author: MatBailie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-28 08:28:30

Desde PostreSQL 9.2 Los tipos de rango son soportados. Así que puedes escribir esto como:

SELECT user_id
FROM user_logs
WHERE '[2014-02-01, 2014-03-01]'::daterange @> login_date

Esto debería ser más eficiente que la comparación de cadenas

 20
Author: Ana María Martínez Gómez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-15 00:47:14

Solo en caso de que alguien aterrice aquí... desde la versión 8.1 puedes simplemente usar:

SELECT user_id 
FROM user_logs 
WHERE login_date BETWEEN SYMMETRIC '2014-02-01' AND '2014-02-28'

De los documentos:

ENTRE SIMÉTRICO es lo mismo que ENTRE excepto que no hay requisito de que el argumento a la izquierda de Y ser menor o igual al argumento de la derecha. Si no lo es, esos dos argumentos son se intercambia automáticamente, de modo que siempre se implica un rango no vacío.

 2
Author: HayrolR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-14 09:28:59

Lea la documentación.

Http://www.postgresql.org/docs/9.1/static/functions-datetime.html

Usé una consulta como esa:

WHERE
(
    date_trunc('day',table1.date_eval) = '2015-02-09'
)

O

WHERE(date_trunc('day',table1.date_eval) >='2015-02-09'AND date_trunc('day',table1.date_eval) <'2015-02-09')    

Juanitos Ingeniero.

 -7
Author: Juan Garfias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-09 18:36:35