我想根据我的db table [member]字段“date_created”获取上个月的记录。
sql是做什么的?
澄清,上个月 - 2009年1月8日至2009年8月31日
如果今天是2010年3月1日,我需要获取2009年1月12日至2009年12月31日的记录。
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()))
你需要检查月份和年份。
WHERE
date_created >= DATEADD(MONTH, DATEDIFF(MONTH, 31, CURRENT_TIMESTAMP), 0)
AND date_created < DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)
我来自Oracle环境,我会在Oracle中这样做:
select * from table
where trunc(somedatefield, 'MONTH') =
trunc(sysdate -INTERVAL '0-1' YEAR TO MONTH, 'MONTH')
想法:我正在运行上个月的预定报告(从第1天到第1天的最后一天,没有窗口)。这可能是索引不友好,但Oracle无论如何都有快速处理日期。在MS SQL中是否有类似的简单和简短的方法?分别比较年份和月份的答案对Oracle人员来说似乎很愚蠢。
SQL查询仅获取当前月份的记录
SELECT * FROM CUSTOMER
WHERE MONTH(DATE) = MONTH(CURRENT_TIMESTAMP) AND YEAR(DATE) = YEAR(CURRENT_TIMESTAMP);
您可以使用此查询获取上个月的记录
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)
在Sql server中最近一个月:
select * from tablename
where order_date > DateAdd(WEEK, -1, GETDATE()+1) and order_date<=GETDATE()
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
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)
我修复类似问题的方法是在我的SELECT部分添加Month
Month DATEADD(day,Created_Date,'1971/12/31') As Month
而且我添加了WHERE语句
Month DATEADD(day,Created_Date,'1971/12/31') = month(getdate())-1
如果您正在寻找上个月,请试试这个,
SELECT
FROM #emp
WHERE DATEDIFF(MONTH,CREATEDDATE,GETDATE()) = 1
如果您正在寻找上个月,请试试这个,
SELECT
FROM #emp
WHERE DATEDIFF(day,CREATEDDATE,GETDATE()) between 1 and 30
一个对我有用的简单查询是:
从表中选择*,其中DATEADD(月,1,DATEFIELD)> = getdate()
所有现有(工作)答案都有两个问题之一:
1.忽略指数:
在大多数情况下,当被搜索的列具有一个被调用的函数时(包括隐式,如CAST
),优化器必须忽略列上的索引并搜索每个记录。这是一个简单的例子:
我们正在处理时间戳,并且大多数RDBMS倾向于将此信息存储为某种增加值,通常是long
或BIGINTEGER
计数毫秒/纳秒。因此,当前时间看起来像这样存储:
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
因此,所有日期操作仅在一个值上执行一次;优化器可以自由使用索引,并且不会包含不正确的数据。
添加到目前为止提供的选项根本不会使用您的索引。
像这样的东西会起作用,并利用表上的索引(如果存在)。
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
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上个月获得
上个月考虑到本月的最后一天。 2016年1月31日这个月的最后一天将是1月31日,这与过去30天不同。
SELECT CONVERT(DATE, DATEADD(DAY,-DAY(GETDATE()),GETDATE()))
一种方法是使用DATEPART函数:
select field1, field2, fieldN from TABLE where DATEPART(month, date_created) = 4
and DATEPART(year, date_created) = 2009
将在4月返回所有日期。对于上个月(即当前月份),您可以使用GETDATE和DATEADD:
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()))
declare @PrevMonth as nvarchar(256)
SELECT @PrevMonth = DateName( month,DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)) +
'-' + substring(DateName( Year, getDate() ) ,3,4)
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()))
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解决方案的另一次升级。 它也给出了上个月的确切最后一天。