获取SQL Server上个月的记录

问题描述 投票:64回答:19

我想根据我的db table [member]字段“date_created”获取上个月的记录。

sql是做什么的?

澄清,上个月 - 2009年1月8日至2009年8月31日

如果今天是2010年3月1日,我需要获取2009年1月12日至2009年12月31日的记录。

sql sql-server tsql
19个回答
92
投票
SELECT * 
FROM Member
WHERE DATEPART(m, date_created) = DATEPART(m, DATEADD(m, -1, getdate()))
AND DATEPART(yyyy, date_created) = DATEPART(yyyy, DATEADD(m, -1, getdate()))

你需要检查月份和年份。


1
投票
WHERE 
    date_created >= DATEADD(MONTH, DATEDIFF(MONTH, 31, CURRENT_TIMESTAMP), 0)
    AND date_created < DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)

1
投票

我来自Oracle环境,我会在Oracle中这样做:

select * from table
where trunc(somedatefield, 'MONTH') =
trunc(sysdate -INTERVAL '0-1' YEAR TO MONTH, 'MONTH')

想法:我正在运行上个月的预定报告(从第1天到第1天的最后一天,没有窗口)。这可能是索引不友好,但Oracle无论如何都有快速处理日期。在MS SQL中是否有类似的简单和简短的方法?分别比较年份和月份的答案对Oracle人员来说似乎很愚蠢。


1
投票

SQL查询仅获取当前月份的记录

SELECT * FROM CUSTOMER
WHERE MONTH(DATE) = MONTH(CURRENT_TIMESTAMP) AND YEAR(DATE) = YEAR(CURRENT_TIMESTAMP);

1
投票

您可以使用此查询获取上个月的记录

SELECT * FROM dbo.member d 
WHERE  CONVERT(DATE, date_created,101)>=CONVERT(DATE,DATEADD(m, datediff(m, 0, current_timestamp)-1, 0)) 
and CONVERT(DATE, date_created,101) < CONVERT(DATE, DATEADD(m, datediff(m, 0, current_timestamp)-1, 0),101) 

0
投票

在Sql server中最近一个月:

select * from tablename 
where order_date > DateAdd(WEEK, -1, GETDATE()+1) and order_date<=GETDATE()

0
投票
DECLARE @curDate INT = datepart( Month,GETDATE())
IF (@curDate = 1)
    BEGIN
        select * from Featured_Deal
        where datepart( Month,Created_Date)=12 AND datepart(Year,Created_Date) = (datepart(Year,GETDATE())-1)

    END
ELSE
    BEGIN
        select * from Featured_Deal
        where datepart( Month,Created_Date)=(datepart( Month,GETDATE())-1) AND datepart(Year,Created_Date) = datepart(Year,GETDATE())

    END 

0
投票
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = dateadd(mm, -1, getdate())
SET @StartDate = dateadd(dd, datepart(dd, getdate())*-1, @StartDate)
SET @EndDate = dateadd(mm, 1, @StartDate)
set @StartDate = DATEADD(dd, 1 , @StartDate)

0
投票

我修复类似问题的方法是在我的SELECT部分​​添加Month

Month DATEADD(day,Created_Date,'1971/12/31') As Month

而且我添加了WHERE语句

Month DATEADD(day,Created_Date,'1971/12/31') = month(getdate())-1

0
投票

如果您正在寻找上个月,请试试这个,

SELECT
FROM  #emp 
WHERE DATEDIFF(MONTH,CREATEDDATE,GETDATE()) = 1

如果您正在寻找上个月,请试试这个,

SELECT
FROM #emp
WHERE DATEDIFF(day,CREATEDDATE,GETDATE()) between 1 and 30

0
投票

一个对我有用的简单查询是:

从表中选择*,其中DATEADD(月,1,DATEFIELD)> = getdate()


76
投票

所有现有(工作)答案都有两个问题之一:

  1. 他们将忽略被搜索列的索引
  2. 意志(可能)选择不打算的数据,静默地破坏您的结果。

1.忽略指数:

在大多数情况下,当被搜索的列具有一个被调用的函数时(包括隐式,如CAST),优化器必须忽略列上的索引并搜索每个记录。这是一个简单的例子:

我们正在处理时间戳,并且大多数RDBMS倾向于将此信息存储为某种增加值,通常是longBIGINTEGER计数毫秒/纳秒。因此,当前时间看起来像这样存储:

1402401635000000  -- 2014-06-10 12:00:35.000000 GMT

你没有在那里看到'年'值('2014'),对吗?事实上,来回翻译需要相当复杂的数学。因此,如果您在搜索列上调用任何提取/日期部分函数,​​则服务器必须执行所有数学计算,以确定是否可以将其包含在结果中。在小桌子上这不是问题,但随着所选行的百分比减少,这变得越来越大。然后在这种情况下,你第二次问这个问题MONTH ......好吧,你得到了照片。

2.意外数据:

根据特定版本的SQL Server和列数据类型,使用BETWEEN(或类似的包含上限范围:<=can result in the wrong data being selected。从本质上讲,您最终可能会在“下一天”的午夜包含数据,或者排除“当前”日记录的某些部分。

你应该做什么:

所以我们需要一种对我们的数据安全的方法,并且将使用索引(如果可行)。那么正确的方式是:

WHERE date_created >= @startOfPreviousMonth AND date_created < @startOfCurrentMonth

鉴于只有一个月,@startOfPreviousMonth可以很容易地替换/派生:

DATEADD(month, -1, @startOCurrentfMonth)

如果需要在服务器中派生当前月初,可以通过以下方式完成:

DATEADD(month, DATEDIFF(month, 0, CURRENT_TIMESTAMP), 0)

这里有一个简短的解释。最初的DATEDIFF(...)将得到当前时代的开始(0001-01-01-AD,CE,等等)之间的差异,基本上返回一个大整数。这是当月开始的月数。然后我们将这个数字添加到时代的开始,即在给定月份的开始。

所以你的完整脚本可能/看起来应该类似于以下内容:

DECLARE @startOfCurrentMonth DATETIME
SET @startOfCurrentMonth = DATEADD(month, DATEDIFF(month, 0, CURRENT_TIMESTAMP), 0)

SELECT *
FROM Member
WHERE date_created >= DATEADD(month, -1, @startOfCurrentMonth) -- this was originally    misspelled
      AND date_created < @startOfCurrentMonth

因此,所有日期操作仅在一个值上执行一次;优化器可以自由使用索引,并且不会包含不正确的数据。


12
投票

添加到目前为止提供的选项根本不会使用您的索引。

像这样的东西会起作用,并利用表上的索引(如果存在)。

DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = dateadd(mm, -1, getdate())
SET @StartDate = dateadd(dd, datepart(dd, getdate())*-1, @StartDate)
SET @EndDate = dateadd(mm, 1, @StartDate)

SELECT *
FROM Member
WHERE date_created BETWEEN @StartDate AND @EndDate

10
投票
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = DATEADD(mm, DATEDIFF(mm,0,getdate())-1, 0)
SET @EndDate = DATEADD(mm, 1, @StartDate)

SELECT *
FROM Member
WHERE date_created BETWEEN @StartDate AND @EndDate

升级到mrdenny的解决方案,这样你就可以从YYYY-MM-01上个月获得


3
投票

上个月考虑到本月的最后一天。 2016年1月31日这个月的最后一天将是1月31日,这与过去30天不同。

SELECT CONVERT(DATE, DATEADD(DAY,-DAY(GETDATE()),GETDATE()))

2
投票

一种方法是使用DATEPART函数:

select field1, field2, fieldN from TABLE where DATEPART(month, date_created) = 4 
and DATEPART(year, date_created) = 2009

将在4月返回所有日期。对于上个月(即当前月份),您可以使用GETDATEDATEADD

select field1, field2, fieldN from TABLE where DATEPART(month, date_created) 
= (DATEPART(month, GETDATE()) - 1) and 
DATEPART(year, date_created) = DATEPART(year, DATEADD(m, -1, GETDATE()))

2
投票
declare @PrevMonth as nvarchar(256)

SELECT @PrevMonth = DateName( month,DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)) + 
   '-' + substring(DateName( Year, getDate() ) ,3,4)

1
投票
select * from [member] where DatePart("m", date_created) = DatePart("m", DateAdd("m", -1, getdate())) AND DatePart("yyyy", date_created) = DatePart("yyyy", DateAdd("m", -1, getdate()))

1
投票
DECLARE @StartDate DATETIME, @EndDate DATETIME    
SET @StartDate = DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)    
SET @EndDate = dateadd(dd, -1, DATEADD(mm, 1, @StartDate))

SELECT * FROM Member WHERE date_created BETWEEN @StartDate AND @EndDate 

以及对mrdenny解决方案的另一次升级。 它也给出了上个月的确切最后一天。

© www.soinside.com 2019 - 2024. All rights reserved.