网上取当月第一天和最后一天的SQL语句不少,有的是经过字符截取,有的是经过函数,我的仍是比较偏向于使用内置函数来处理,算法
可是看了下网上的运用函数来取第一天和最后一天时间的SQL语句几乎都像下面这样的,实际上是存在问题的,存在一个临界值得问题。sql
本月第一天:select dateadd(dd,-day(getdate())+1,getdate()) 函数
本月最后一天:select dateadd(dd,-day(getdate()),dateadd(m,1,getdate()))
上面的两句,第一句取第一天的彻底没问题,第二句就有问题了,通常的想法是取最后一天,能够在当前时间上加一个月,而后减去当前时间的天数,好比随便 2009-8-27,加一个月就是2009-9-27,而后减去2009-8-27时间的天数27天 正好是2009-8-31,没问题呀。测试
可是,若是当前时间自己就是最后一天的话,就会产生临界问题了,好比传入的实际是2009-5-31,最终获得的最后一天的时间其实也应该是 2009-5-31才对,若是按照上面的写法,2009-5-31加一个月是多少,2009-6-31?2009-7-1?都不是,因为月大月小的问 题,6月份只有30天,因此2009-5-31加一个月后是2009-6-30日,仍是按上面的写法而后再减去2009-5-31时间的天数31天,最终 获得的最后一天是2009-5-30,傻眼了,咋回事啊?spa
还有2月只有28或29天固然也会存在这样的问题,只要稍微改动一下,在减天数的时候不该减当前时间的天数,而应减去加了月份以后的天数,以下写法:
select dateadd(dd,-day(dateadd(m,1,getdate())),dateadd(m,1,getdate()))日志
这样的话,即便6月没有31天,2009-6-30减去30天就是2009-5-31,再如2009-1-30加一个月是2009-2-28,减去28天后是2009-1-31符合正确性。code
能够依此类推:blog
能够依此类推:get
select dateadd(dd,-day(dateadd(month,-1,getdate()))+1,dateadd(month,-1,getdate())) /*上个月一号*/
select dateadd(dd,-day(getdate()),getdate()) /* 上月月底 */
select dateadd(dd,-day(getdate())+1,getdate()) /* 本月一号 */
select dateadd(dd,-day(dateadd(month,1,getdate())),dateadd(month,1,getdate())) /* 本月底 */
select dateadd(dd,-day(dateadd(month,1,getdate()))+1,dateadd(month,1,getdate())) /* 下月一号 */
select dateadd(dd,-day(dateadd(month,2,getdate())),dateadd(month,2,getdate())) /* 下月月底 */it
若是想把时间格式转换成“yyyy/mm/dd hh:mi:ss”这种格式,能够:
select rtrim(convert(char,getdate(),111))+''+(convert(char,getdate(),108)) -- yyyy/mm/dd hh:mi:ss
测试:(列出上月开始和结束时间,而后转换时间格式)
declare @time1 datetime,
@time2 datetime,
@time3 datetime,
@time4 datetime
set @time1 = dateadd(dd,-day(dateadd(month,-1,getdate()))+1,dateadd(month,-1,getdate())), --上个月一号
@time2 = dateadd(dd,-day(getdate())+1,getdate()) --本月一号
set @time3 = rtrim(convert(char,@time1,111))+''+(convert(char,@time1,108)),
@time4 = rtrim(convert(char,@time2,111))+''+(convert(char,@time2,108))
select dateadd(dd,-day(dateadd(month,-1,getdate()))+1,dateadd(month,-1,getdate()))
select dateadd(dd,-day(getdate())+1,getdate())
select rtrim(convert(char,@time1,111))+''+(convert(char,@time1,108)) -- yyyy/mm/dd hh:mi:ss
select rtrim(convert(char,@time2,111))+''+(convert(char,@time2,108)) -- yyyy/mm/dd hh:mi:ss
输出结果:(sybase下)
Jan 1 2011 5:30PM
-
Feb 1 2011 5:30PM
-
2011/01/01 17:30:58
-
2011/02/01 17:30:58
------==========T-SQL 经常使用星期设置============------- --所在星期的第一天,计算给定日期所在星期的第1天(星期日为第一天) DECLARE @Date DATETIME SET @Date= GETDATE() --与SQL Server语言版本相关的算法 --思路:当前日期+星期日(每周的第1天)与当前日期的差的天数 --DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关 SET DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天) SELECT DATEADD(WEEKDAY,1-DATEPART(WEEKDAY,@Date),@Date) AS 所在星期的第一天 --星期日,与SQL Server语言版本或@@DATEFIRST无关 --1899-12-31 是星期日,1899-12-31 再加上(当前日期与 1899-12-31差的星期数)个星期 SELECT DATEADD(WEEK,DATEDIFF(WEEK,-1,@Date),-1) AS 所在星期的星期日 --或者 SELECT DATEADD(WEEK,DATEDIFF(WEEK,6,@Date),6) AS 所在星期的星期日 GO --所在星期的次日,计算给定日期所在星期的第2天(星期日为第一天) DECLARE @Date DATETIME SET @Date= GETDATE() --DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关 SET DATEFIRST 7 -- SELECT DATEADD(DAY,2-DATEPART(WEEKDAY,@Date),@Date) AS 所在星期的次日 --'1900-01-01' 是星期一,'1900-01-01' 再加上(当前日期与'1900-01-01'差的星期数)个星期 SELECT DATEADD(WEEK,DATEDIFF(WEEK,0,@Date),0) AS 所在星期的星期一 GO --上个星期第一天,计算给定日期所在星期的上一个星期日(星期日为第一天) DECLARE @Date DATETIME SET @Date= GETDATE() --思路:当前日志所在星期的星期日再减1周 --DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关 --SET DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天) SELECT DATEADD(WEEK,-1,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS 上个星期第一天 --一周等于7天 SELECT DATEADD(DAY,-7,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS 上个星期第一天 --简化 SELECT DATEADD(DAY,-6-DATEPART(WEEKDAY,@Date),@Date) AS 上个星期第一天 --上个星期日,与SQL Server语言版本或@@DATEFIRST无关 SELECT DATEADD(WEEK,-1+DATEDIFF(WEEK,-1,@Date),-1) AS 上个星期日 --或者 SELECT DATEADD(WEEK,DATEDIFF(WEEK,6,@Date),-1) AS 上个星期日 GO --下个星期第一天,计算给定日期所在星期的下一个星期日(星期日为第一天) DECLARE @Date DATETIME SET @Date= GETDATE() SET DATEFIRST 7 SELECT DATEADD(WEEK,1,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS 下个星期第一天 --一周等于7天 SELECT DATEADD(DAY,7,DATEADD(DAY,1-DATEPART(WEEKDAY,@Date),@Date)) AS 下个星期第一天 --简化 SELECT DATEADD(DAY,8-DATEPART(WEEKDAY,@Date),@Date) AS 下个星期第一天 --下个星期日,与SQL Server语言版本或@@DATEFIRST无关 SELECT DATEADD(WEEK,1+DATEDIFF(WEEK,-1,@Date),-1) AS 下个星期日 --或者 SELECT DATEADD(WEEK,DATEDIFF(WEEK,-1,@Date),6) AS 下个星期日 GO --判断给定日期是星期几 DECLARE @Date DATETIME SET @Date= GETDATE() --DATEPART(WEEKDAY,DATE)的返回值与@@DATEFIRST相关 SET DATEFIRST 7 -- 或者设置为美国英语SET LANGUAGE us_english; (星期日为第一天) SELECT DATEPART(WEEKDAY,@Date) --返回值 1-星期日,2-星期一,3-星期二......7-星期六 --上面算法与SQL 语言版本或 @@DATEFIRST 相关 --下面算法与SQL Server语言版本或@@DATEFIRST无关 SELECT DATENAME(WEEKDAY,@Date) 星期 GO
在本文中,GetDate()得到的日期由两部分组成,分别是今天的日期和当时的时间: Select GetDate()
用DateName()就能够得到相应的年、月、日,而后再把它们链接起来就能够了:
Select Datename(year,GetDate())+'-'+Datename
(month,GetDate())+'-'+Datename(day,GetDate())
另外,DateName()还能够得到到小时、时间、秒、星期几、第几周,分别以下:
Select Datename(hour,GetDate())
Select Datename(minute,GetDate())
Select Datename(second,GetDate())
Select Datename(weekDay,GetDate())
Select Datename(week,GetDate())
SQL中的日期类型DateTime的默认格式就是yyyy-mm-dd hh:mi:ss: mmm,可大多数的状况咱们只想获得他的日期部分,而不准要后面的时间。上一篇中提到用Datename()函数来截取拼接出不包含时间部分的日期,如今再说一种方法,更加简单的获取到不包含时间的日期!
使用Convert()函数:
select convert(char(10),GetDate(),120) as Date
* 第3个参数就是用来设置日期类型数据的显示样式的,下面介绍几种样式的参数:
100 mm dd yyyy
101 mm/dd/yyyy
102 yyyy.mm.dd
103 dd/mm/yyyy
106 dd mm yyyy
108 hh:mi:ss(时间)
111 yyyy/mm/dd
112 yyyymmdd
120 yyyy-mm-dd
DECLARE @ThisWeekStartTime NVARCHAR(100),@ThisWeekEndTime NVARCHAR(100),--本周 @LastWeekStartTime NVARCHAR(100),@LastWeekEndTime NVARCHAR(100),--上周 @ThisMonthStartTime NVARCHAR(100),@ThisMonthEndTime NVARCHAR(100),--本月 @LastMonthSartTime NVARCHAR(100),@LastMonthEndTime NVARCHAR(100),--上月 @LastestHalfYearStartTime NVARCHAR(100),@LastestHalfYearEndTime NVARCHAR(100),--近半年 @LastestOneYearStartTime NVARCHAR(100),@LastestOneYearEndTime NVARCHAR(100)--近一年 SELECT @ThisWeekStartTime= CONVERT(nvarchar(10), DATEADD(wk, DATEDIFF(wk,0,DATEADD(dd, -1, getdate()) ), 0),121)--本周开始时间 SELECT @ThisWeekEndTime= CONVERT(nvarchar(10), DATEADD(wk, DATEDIFF(wk,0,DATEADD(dd, -1, getdate()) ), 6),121)--本周结束时间 SELECT @LastWeekStartTime= CONVERT(nvarchar(10),DATEADD(wk, DATEDIFF(wk,0,DATEADD(dd, -7, getdate()) ), 0),121)--上周开始时间 SELECT @LastWeekEndTime= CONVERT(nvarchar(10), DATEADD(wk, DATEDIFF(wk,0,DATEADD(dd, -7, getdate()) ), 6),121)--上周结束时间 SELECT @ThisMonthStartTime=CONVERT(nvarchar(10),dateadd(dd,-day(getdate())+1,getdate()),121)--本月开始时间 SELECT @ThisMonthEndTime=CONVERT(nvarchar(10),dateadd(dd,-day(getdate()),dateadd(m,1,getdate())),121)--本月结束时间 SELECT @LastMonthSartTime=CONVERT(nvarchar(10),dateadd(dd,-day(dateadd(month,-1,getdate()))+1,dateadd(month,-1,getdate())),121)--上月开始时间 SELECT @LastMonthEndTime= CONVERT(nvarchar(10), dateadd(dd,-day(getdate()),getdate()),121) --上月结束时间 SELECT @LastestHalfYearStartTime= CONVERT(nvarchar(10), dateadd(dd,-day(dateadd(month,-6,getdate()))+1,dateadd(month,-6,getdate())) ,121)--近半年开始时间 SELECT @LastestHalfYearEndTime=CONVERT(nvarchar(10), dateadd(dd,-day(getdate()),getdate()),121)--近半年结束时间 SELECT @LastestOneYearStartTime= CONVERT(nvarchar(10), dateadd(dd,-day(dateadd(month,-12,getdate()))+1,dateadd(month,-12,getdate())) ,121)--近一年开始时间 SELECT @LastestOneYearEndTime=CONVERT(nvarchar(10), dateadd(dd,-day(getdate()),getdate()),121)--近一年结束时