Con fechas (y horas) muchas cosas se simplifican 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, aún necesita calcular la fecha de inicio del mes que necesita, pero eso debería ser sencillo de varias maneras.
La fecha de finalización también se simplifica; simplemente agregue exactamente un mes. No te metas con los días 28, 30, 31, etc.
Esta estructura también tiene la ventaja de poder mantener el uso de índices.
Muchas personas pueden sugerir un formulario como el siguiente, pero no usar í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 el índice para encontrar el rango de filas que coincidirán (una búsqueda de rango).