Consulta para obtener todas las filas del mes anterior


90

Necesito seleccionar todas las filas de mi base de datos que se crearon el mes pasado.

Por ejemplo, si el mes actual es enero, quiero devolver todas las filas que se crearon en diciembre, si el mes es febrero, quiero devolver todas las filas que se crearon en enero. Tengo una date_createdcolumna en mi base de datos que muestra la fecha creada en este formato: 2007-06-05 14:50:17.

Respuestas:


198
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)

70
SELECT * FROM table WHERE date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();
Ghazanfar Mir

12
@GhazanfarMir su consulta no coincide con la pregunta, mientras que la respuesta anterior sí lo hace. El suyo devuelve las filas entre este día del mes pasado y ayer.
Matt Passell

@MattPassell Lo siento, pero betweenincluye los límites. También incluirá la fecha actual. ¿Por qué / cómo se limitará a ayer? ¿Por favor elabora?
Ghazanfar Mir

4
Entiendo lo que quieres decir ... Sí, tienes razón ... mi consulta no es lo que OP quería ... Entendí mal la pregunta
Ghazanfar Mir

¿Qué pasa si current_dateno es hoy sino una fecha aleatoria dada por el cliente?
dios231

22

Aquí tienes otra alternativa. Suponiendo que tiene un campo indexado DATEo de DATETIMEtipo, esto debería usar el índice, ya que las fechas formateadas se convertirán antes de usar el índice. A continuación, debería ver una rangeconsulta en lugar de una indexconsulta cuando se ve con EXPLAIN .

SELECT
    * 
FROM
    table
WHERE 
    date_created >= DATE_FORMAT( CURRENT_DATE - INTERVAL 1 MONTH, '%Y/%m/01' ) 
AND
    date_created < DATE_FORMAT( CURRENT_DATE, '%Y/%m/01' )

+1. Mucho más amigable con los índices. También puede lanzar un STR_TO_DATEalrededor DATE_FORMATpara que siempre se trate de objetos de fecha.
Leigh

14

Si no hay fechas futuras ...

SELECT * 
FROM   table_name 
WHERE  date_created > (NOW() - INTERVAL 1 MONTH);

Probado.


3
Creo que buscaban algo diferente. es decir, todos los registros del mes pasado (es decir, del 1 de octubre al 31 de octubre de 2012 a las 23:59:59). La consulta anterior devolvería los últimos ~ 30 días aproximadamente, desde la fecha y hora de hoy .
Leigh

13

Alternativamente a la respuesta de hobodave

SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)

Podría lograr lo mismo con EXTRACT, usando YEAR_MONTH como unidad, por lo que no necesitaría el AND, así:

SELECT * FROM table
WHERE EXTRACT(YEAR_MONTH FROM date_created) = EXTRACT(YEAR_MONTH FROM CURDATE() - INTERVAL
1 MONTH)

Esto funciona muy bien durante meses, pero desafortunadamente no hay un YEAR_WEEK intervalo temporal , por lo que tendría que recurrir a la respuesta de hobodave si necesita semanas en lugar de meses.
Danny Beckett

8
SELECT *
FROM  yourtable
where DATE_FORMAT(date_created, '%Y-%m') = date_format(DATE_SUB(curdate(), INTERVAL 1 month),'%Y-%m')

Esto debería devolver todos los registros del mes calendario anterior, a diferencia de los registros de los últimos 30 o 31 días.


Olvidé mencionar ... esto debería devolver todos los registros del mes calendario anterior, a diferencia de los registros de los últimos 30 o 31 días.
Gregg

En mi opinión, esta debería ser la respuesta aceptada, ya que es más simple que la respuesta aceptada pero proporciona el mismo resultado
Grant

3

Aunque la respuesta para esta pregunta ya ha sido seleccionada, creo que la consulta más simple será

SELECT * 
FROM table 
WHERE 
date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();

2
No, no del todo. Vea mi respuesta a su comentario sobre la respuesta dada por @hobodave
Matt Passell

@MattPassell Tiene razón, entendí mal la pregunta ... Me perdí el punto de que el resultado debe limitarse SOLAMENTE a los registros del mes pasado.
Ghazanfar Mir

2
WHERE created_date >= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 2 MONTH)), INTERVAL 1 DAY) 
  AND created_date <= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)), INTERVAL 0 DAY) 

Esto funcionó para mí (selecciona todos los registros creados desde el mes pasado, independientemente del día en que ejecute la consulta este mes)


1

select fields FROM table WHERE date_created LIKE concat(LEFT(DATE_SUB(NOW(), interval 1 month),7),'%');

este podrá aprovechar un índice si su date_created está indexado, porque no aplica ninguna función de transformación al valor del campo.


@ggiroux - Sin embargo, tiene que convertir la fecha a un tipo de carácter antes de aplicar LIKE.
Martin Clayton

sí, de hecho, pero sigue siendo una mejora con respecto a la respuesta seleccionada en mi humilde opinión (IFF date_created está indexado)
ggiroux

1

Aquí está la consulta para obtener los registros del último mes:

SELECT *
FROM `tablename`
WHERE `datefiled`
BETWEEN DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH )
AND 
LAST_DAY( DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH ) )

Saludos - saqib


¿Ha intentado ejecutar esa consulta? Por lo que veo, no seleccionaría todas las fechas de los meses anteriores (como en: devolver datos de enero a lo largo de todo febrero), pero devolvería datos de un rango que comenzó el mismo día hace un mes
Nico Haase

0

Alternativa con condición única

SELECT * FROM table
WHERE YEAR(date_created) * 12 + MONTH(date_created)
    = YEAR(CURRENT_DATE) * 12 + MONTH(CURRENT_DATE) - 1

-1
SELECT *  FROM table  
WHERE  YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)

¿Ha intentado ejecutar esa consulta? Por lo que veo, no seleccionaría todas las fechas de los meses anteriores (como en: devolver datos de enero a lo largo de todo febrero), pero devolvería datos de un rango que comenzó el mismo día hace un mes
Nico Haase

Hice algunos cambios, verifique si funciona o no
sid busa
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.