[mysql] Query to get all rows from previous month

I need to select all rows in my database that were created last month.

For example, if the current month is January, then I want to return all rows that were created in December, if the month is February, then I want to return all rows that were created in January. I have a date_created column in my database that lists the date created in this format: 2007-06-05 14:50:17.

This question is related to mysql

The answer is


Here is the query to get the records of the last month:

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

Regards - saqib


Even though the answer for this question has been selected already, however, I believe the simplest query will be

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

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

This should return all the records from the previous calendar month, as opposed to the records for the last 30 or 31 days.


Alternative with single condition

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

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

this one will be able to take advantage of an index if your date_created is indexed, because it doesn't apply any transformation function to the field value.


Here's another alternative. Assuming you have an indexed DATE or DATETIME type field, this should use the index as the formatted dates will be type converted before the index is used. You should then see a range query rather than an index query when viewed with 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' )

Alternatively to hobodave's answer

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

You could achieve the same with EXTRACT, using YEAR_MONTH as unit, thus you wouldn't need the AND, like so:

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

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

If there are no future dates ...

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

Tested.


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) 

This worked for me (Selects all records created from last month, regardless of the day you run the query this month)