2017-03-07 63 views
0

我使用的是SQL Server 2008 R2和需要通过选择开始和结束日期与月份的最后一天返回的所有数据:如何获得一个月(SQL Server)的最后一天

当用户选择两个日期是这样的:

开始日期:2017-01-01

结束日期:2017-22-02

结果必须是: 2017-31-012017-22-02

我尝试下面的代码,但我得到了错误的结果=>2017-28-02

SELECT 
    DATEADD(d, -1, DATEADD(mm, DATEDIFF(m, 0,'2017-22-02') + 1, 0)) AS DiffDate, 
    MEMBER_ID 
FROM 
    dbo.tblOne 
WHERE 
    DATUM >= '2017-01-01' 
AND 
    DATUM <= '2017-22-02' 

任何人都可以有一个想法是什么,我做错了?

编辑: 我希望以下结果:

DiffDate | MemberID | ... 
--------------------------------- 
    2017-01-31 | CBK01 
    2017-01-31 | KKM05 
    2017-01-31 | ABC99 
    2017-02-22 | CBK01 
    2017-02-22 | KKM05 
    2017-02-22 | ABC99 
+0

@AndrewMorton通常我总是使用这种格式'YYYY-MM-dd'但今天的SQL Server管理工作室只接受'yyyy-dd-MM' ......我不知道为什么。 – yuro

+0

@AndrewMorton - 我们自己的,根据SQL Server开发人员的智慧 - 如果你设置了dateformat dmy或set language british_english,那么你会发现它也颠倒了它接受'nnnn-nn-nn'格式。这就是为什么为了安全起见,你应该使用'yyyyMMdd',也就是说,不要使用分隔符(如果你有时间的话可以使用'yyyy-MM-ddThh:mm:ss') - SQL Server不会出错。 –

+0

我完全不清楚你在这里要做什么 - 可能会添加一些*样本数据*和*预期结果*。你的叙述难以遵循。 –

回答

0

我使用UDF fn_DateSerial来简化这些日期的操作:

--sample value 
Declare @Startdate datetime 
set @Startdate = GetDate() 

--last day of month 
select DateAdd(month, 1, dbo.fn_DateSerial(Year(@Startdate),Month(@Startdate),1,0,0,0,0)) - 1 

所以基本上我条纹日部分(使其第一天),然后添加1个月,最后减去一天。

这个UDF的灵感来自同名vb6函数。

/* 
Function composes datetime from its parts - year, month, day, minute, etc. 
*/ 
CREATE FUNCTION dbo.fn_DateSerial(@year int, @month int, @day int, @hour int, @minute int, @second int, @millisecond int) RETURNS datetime 
BEGIN 
    DECLARE @dt datetime, @dtStr varchar(255) 
    --mm/dd/yyyy hh:mi:ss.mmm(24h) 
    SET @dtStr = '' 
    SET @dtStr = @dtStr + right('00'+convert(varchar(2), @month),2) + '/' 
    SET @dtStr = @dtStr + right('00'+convert(varchar(2), @day),2) + '/' 
    SET @dtStr = @dtStr + right('0000'+convert(varchar(4),@year),4) 

    SET @dtStr = @dtStr + ' ' + right('00'+convert(varchar(2), @hour),2) + ':' 
    SET @dtStr = @dtStr + right('00'+convert(varchar(2), @minute),2) + ':' 
    SET @dtStr = @dtStr + right('00'+convert(varchar(2), @second),2) + '.' 
    SET @dtStr = @dtStr + right('000'+convert(varchar(3), @millisecond),3) 

    SET @dt = CONVERT(datetime, @dtStr, 101) 

    return @dt 
END 
+0

感谢您的回答,但这太复杂了。有一个更聪明的解决方案。 – yuro

+0

然后'选择DATEADD(month,DATEDIFF(month,0,@ Startdate)+1,0) - 1'是要走的路。这与您输入的内容完全相同,并且工作正常。如果它不适合你 - 在其他地方(不包括日期)出现问题。 –

0

离开解决方案的日期格式在这里,但这是你真正需要解决的问题。据我所知,你只需要找到给定日期前一个月的最后一天。这将使用getdate()作为基础。您可以轻松地将getdate()更改为数据中的一列。

select LastDayOfPreviousMonth = dateadd(day, -1, dateadd(month, datediff(month, 0, GETDATE()), 0)) 
0

我可以建议此方法来获取一个月的日期的最后日期:

declare @date datetime = '2017-04-22'; 

select 
    dateadd(d, 
     -datepart(d,@date) -- count of days of @date to get back 
     ,dateadd(m,1,@date) -- get date of next month of @date 
    ) lastDate 
相关问题