特别是 MSSQL 2005。
9 回答
这是一个解决方案,可为您提供当月的最后一秒。您可以提取日期部分或对其进行修改以仅返回日期。我在 SQL Server 2005 上对此进行了测试。
select dateadd( s, -1, dateadd( mm, datediff( m, 0, getdate() ) + 1, 0 ) );
要了解它是如何工作的,我们必须查看dateadd()和datediff()函数。
DATEADD(datepart, number, date)
DATEDIFF(datepart, startdate, enddate)
如果您只运行对 datediff() 的最内部调用,您将获得自时间戳 0 以来的当前月份数。
select datediff(m, 0, getdate() );
1327
下一部分将该月数加上 1 加到 0 时间戳中,为您提供下一个日历月的起点。
select dateadd( mm, datediff( m, 0, getdate() ) + 1, 0 );
2010-09-01 00:00:00.000
最后,外部 dateadd() 只是从下个月的开始时间戳中减去一秒,为您提供当月的最后一秒。
select dateadd( s, -1, dateadd( mm, datediff( m, 0, getdate() ) + 1, 0 ) );
2010-08-31 23:59:59.000
这个旧答案(如下)有一个错误,它在一个月的最后一天不起作用,比下个月有更多的天数。我把它留在这里作为对其他人的警告。
将一个月添加到当前日期,然后使用函数 DAY 和 DATEADD 减去应用于当前日期的 DAY 函数返回的值。
dateadd(day, -day(getdate()), dateadd(month, 1, getdate()))
SELECT DATEADD(M, DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), '1990-01-31T00:00:00.000')
解释:
一般方法:使用时间功能。
SELECT '1990-01-01T00:00:00.000', '1990-01-31T00:00:00.000'
这些是 DATETIME 文字,分别是同一 31 天月份的第一天和最后一天的第一个时间颗粒。选择哪个月份是完全任意的。
SELECT DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP)
这是参考月份的第一天和当前时间戳之间的整月差异。让我们称之为@calc
.
SELECT DATEADD(M, @calc, '1990-01-31T00:00:00.000')
这会将@calc
月份粒度添加到参考月份的最后一天,其结果是将当前时间戳“四舍五入”到其月份的最后一天。量子点
试试这个:
DATEADD (DAY, -1, DATEADD (MONTH, DATEDIFF (MONTH, 0, CURRENT_TIMESTAMP) + 1, 0)
他们的关键点是您是否可以获得当月的第一天、上个月的最后一天和当月的最后一天。
下面是逐步编写查询的方法:
在 SQL Server 中,日期从 1901/01/01(日期 0)开始,直到现在每个月都可以用一个数字来标识。12 月是 1902 年的第一个月,意思是一月。1200 月是 2001 年 1 月。类似地,每一天都可以分配唯一的编号,例如日期 0 是 1901/01/01。日期 31 是 1901/02/01,因为 1901 年 1 月从 0 开始。
找出当前月份的第一天(当前日期或给定日期)
- 首先,我们需要检查自日期 0(1901/01/01) 以来已经过去了多少个月。选择日期(MM,0,GETDATE())
- 添加相同的月份日期 0(1901/01/01)
选择 DATEADD(MM, DATEDIFF(MM,0,GETDATE()),0)
然后我们将获得当前月份的第一天(当前日期或给定日期)
获取上个月的最后一天
我们需要从当月的第一天减去一秒
选择 DATEADD(SS,-1,DATEADD(MM, DATEDIFF(MM,0,GETDATE()),0))
获取当月的最后一天
为了首先获取当前月份的第一天,我们检查了自日期 0(1901/01/01) 以来已经过去了多少个月。如果我们再添加一个自日期 0 以来的总月数,然后添加日期为 0 的总月数,我们将得到下个月的第一天。
SELECT DATEADD(MM, DATEDIFF(MM,0,GETDATE())+1,0)
如果我们得到下个月的第一天然后得到当月的最后一天,我们只需要减去一秒钟。
选择 DATEADD(SS,-1,DATEADD(MM, DATEDIFF(MM,0,GETDATE())+1,0))
希望这会有所帮助。
使用 SQL2005,您无法访问有用的功能EOMONTH()
,因此您必须自己计算。
这个简单的功能将类似于EOMONTH
CREATE FUNCTION dbo.endofmonth(@date DATETIME= NULL)
RETURNS DATETIME
BEGIN
RETURN DATEADD(DD, -1, DATEADD(MM, +1, DATEADD(DD, 1 - DATEPART(DD, ISNULL(@date,GETDATE())), ISNULL(@date,GETDATE()))))
END
要执行的查询:
SELECT dbo.endofmonth(DEFAULT) --Current month-end date
SELECT dbo.endofmonth('02/25/2012') --User-defined month-end date
一些可能答案的链接:
DECLARE
@Now datetime,
@Today datetime,
@ThisMonth datetime,
@NextMonth datetime,
@LastDayThisMonth datetime
SET @Now = getdate()
SET @Today = DateAdd(dd, DateDiff(dd, 0, @Now), 0)
SET @ThisMonth = DateAdd(mm, DateDiff(mm, 0, @Now), 0)
SET @NextMonth = DateAdd(mm, 1, @ThisMonth)
SET @LastDayThisMonth = DateAdd(dd, -1, @NextMonth)
有时你确实需要这个月的最后一天,但很多时候你真正想要的是描述这个月的时间间隔。这是描述本月时间间隔的最佳方式:
WHERE @ThisMonth <= someDate and someDate < @NextMonth
为了完整起见,在 Oracle 中,您会执行类似...
select add_months(trunc(sysdate,'MM'),1) ...
或者
select last_day(sysdate)+1 ...
DATEADD(dd, -1, DATEADD(mm, +1, DATEADD(dd, 1 - DATEPART(dd, @myDate), @myDate)))