網上取當月第一天和最後一天的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)--近一年結束時