查询以获取上个月的所有行


90

我需要选择数据库中上个月创建的所有行。

例如,如果当前月份是一月,那么我想返回在十二月创建的所有行,如果月份是二月,那么我想返回在一月份创建的所有行。date_created我的数据库中有一列,以这种格式列出创建日期:2007-06-05 14:50:17

Answers:


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

11
@GhazanfarMir您的查询与问题不完全匹配,而上面的答案却与之匹配。您将返回上个月的这一天到昨天之间的行。
马特·帕瑟

@MattPassell很抱歉,但between包含边界。.它将也包括当前日期。为什么/如何仅限于昨天?请详细说明?
Ghazanfar Mir

4
我明白你的意思..是的,你是对的..我的查询是不是OP想..我误解了这个问题
Ghazanfar米尔

如果current_date不是今天而是客户指定的随机日期怎么办?
dios231 '16

22

这是另一种选择。假设您有一个索引字段DATEDATETIME类型字段,则应使用索引,因为格式化的日期将在使用索引之前进行类型转换。当使用EXPLAIN查看时,您应该看到的是range查询而不是index查询。

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。索引友好得多。您也可以使用STR_TO_DATEDATE_FORMAT所以它总是与日期对象打交道。
Leigh 2012年

14

如果没有将来的日期...

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

经过测试。


3
我认为他们正在寻找与众不同的东西。即上个月的所有记录(即2012年10月1日至10月31日23:59:59)。上面的查询将返回距离今天的日期和时间最近30天左右的时间
Leigh 2012年

13

替代hobodave的答案

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

您可以使用YEAR_MONTH作为单位,使用EXTRACT达到相同的目的,因此不需要AND,就像这样:

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

这可以持续数月,但不幸的是没有YEAR_WEEK 时间间隔,因此,如果您需要数周而不是数月的时间,则必须退回到hobodave的答案。
丹尼·贝克特

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

这应返回上一个日历月的所有记录,而不是最近30或31天的记录。


我忘了提...这应该返回上一个日历月的所有记录,而不是过去30或31天的记录。
Gregg

我认为这应该是公认的答案,因为它比公认的答案更简单,但提供相同的结果
Grant

3

尽管已经选择了该问题的答案,但是我相信最简单的查询是

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

2
不,不是。请参阅我对您对@hobodave给出的答案的评论的回复-Matt Passell
2014年

@MattPassell是的,我误解了这个问题。我错了一点,即结果只应限于上个月的记录。
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) 

这对我有用(选择上个月创建的所有记录,而不管本月运行查询的日期如何)


1

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

如果您的date_created已建立索引,则此索引将能够利用索引,因为它不会对字段值应用任何转换函数。


@ggiroux-确实必须在应用LIKE之前将日期转换为字符类型。
马丁克莱顿

是的,的确如此,但是仍然比所选答案更好(恕我直言(IFF date_created已建立索引)
ggiroux 2010年

1

这是获取上个月记录的查询:

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

问候-saqib


您是否尝试运行该查询?据我所知,它不会选择前几个月的所有日期(例如:返回整个2月的1月数据),而是返回一个月前同一天开始的范围内的数据
Nico Haase

0

单一条件的替代

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)

您是否尝试过运行该查询?据我所知,它不会选择前几个月的所有日期(例如:返回整个2月的1月数据),而是返回一个月前同一天开始的范围内的数据
Nico Haase

我进行了一些更改,现在检查是否正常工作
sid busa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.