SQL日期函數(shù)詳解與實戰(zhàn)

編寫SQL中經(jīng)常可以遇到日期的格式化與日期相關(guān)函數(shù)盟猖,這篇文章中我們將整理一下相關(guān)函數(shù)并給出一些實例供參考

獲取時間函數(shù)

getdate()函數(shù)

getdate()函數(shù)獲取當前的日期與時間。返回的為datetime類型

select GETDATE()

返回2020-09-21 10:07:38.170

SYSDATETIME()函數(shù)

SYSDATETIME()函數(shù)獲取當前的日期與時間,但是返回的數(shù)據(jù)類型是DATETIME2凹嘲,會更加精準呜魄,使用頻率較少

SELECT SYSDATETIME()

格式化函數(shù)

CONVERT()函數(shù)

CONVERT() 函數(shù)是一個數(shù)據(jù)類型轉(zhuǎn)化的通用函數(shù)悔叽,例如將數(shù)字類型轉(zhuǎn)化為文本等。我們可以使用此函數(shù)把日期轉(zhuǎn)換為新數(shù)據(jù)類型
語法為:

        CONVERT(data_type(length),expression,style)

其中data_type(length) 規(guī)定目標數(shù)據(jù)類型(帶有可選的長度)爵嗅。expression指需要轉(zhuǎn)換的值娇澎。style 規(guī)定日期/時間的輸出格式。

其中常用的style代碼及顯示格式如下:

        101: mm/dd/yyyy
        110: mm-dd-yyyy
        111: yyyy/mm/dd
        112: yyyymmdd
        120: yyyy-mm-dd hh:mm:ss
        121: yyyy-mm-dd hh:mm:sssssss

全部的style代碼可以參考:https://www.cnblogs.com/rainman/p/6558261.html

例如;

    SELECT CONVERT(varchar(100), GETDATE(), 111)

通過查看轉(zhuǎn)化后的數(shù)據(jù)類型睹晒,可以看到新的數(shù)據(jù)類型已變成varchar(100)類型趟庄。

--查看數(shù)據(jù)類型
DECLARE @query nvarchar(max) = 'SELECT CONVERT(varchar(100), GETDATE(), 111) AS [Column1]';
EXEC sp_describe_first_result_set @query, null, 0;

FORMAT()函數(shù)

Format函數(shù)用于指定顯示的格式。
語法:

FORMAT(value,format[,culture])

參數(shù)format用于指定顯示的格式伪很,給予用戶對格式更自由地控制戚啥,culture參數(shù)是可選的,用于指定顯示的語言锉试,該函數(shù)返回值的數(shù)據(jù)類型是NVARCHAR猫十,如果格式轉(zhuǎn)換失敗,該函數(shù)返回NULL

參數(shù)format使用#表示一個數(shù)值,參數(shù) format 使用以下占位符來表示日期/時間的格式:

1. yyyy炫彩、MM匾七、dd:表示年、月江兢、日
2. hh:mm:ss fffffff:表示時昨忆、分、秒杉允、毫秒
3. 使用“/”邑贴,“-”等作為連接各個部分(part)的分割符號

例如要將當前日期轉(zhuǎn)化為20200921,則SQL語句為:

SELECT Format(GETDATE(), 'yyyyMMdd')

同時format()函數(shù)還可以轉(zhuǎn)變數(shù)值類型叔磷,使用特定的格式展示等

select FORMAT(123456789,'###-##-####') AS 'Custom Number Result'

對應返回結(jié)果為123-45-6789

日期的拆分與拼接(構(gòu)造)

YEAR(date),MONTH(date),DAY(date)

YEAR(date),MONTH(date),DAY(date)等函數(shù)返回給定date的年拢驾,月,日
實例:

select year('2020-9-21'),month('2020-9-21'),day('2020-9-21')

DATEPART() 函數(shù)

DATEPART() 函數(shù)用于返回日期/時間的單獨部分改基,比如年繁疤、月、日秕狰、小時稠腊、分鐘等等

語法:

DATEPART(datepart,date)

其中date 參數(shù)是合法的日期表達式。datepart為需要取出的數(shù)據(jù)縮寫代碼鸣哀。常用的datepart參數(shù)可以是下列的值:

    quarter:季度架忌,取值范圍是 1、2我衬、3叹放、4
    week:周在年中的序數(shù),取值范圍是 1 - 53
    dayofyear:天在年中的序數(shù)挠羔,取值范圍是 1 - 366
    weekday:天在一周中的序數(shù)井仰,取值范圍是 1 - 7

全部參數(shù)可參閱:https://www.w3school.com.cn/sql/func_datepart.asp

具體實例代碼:

--返回年,月份破加,季度糕档,當前天數(shù)統(tǒng)計
SELECT DATEPART(yyyy,GETDATE()) AS Year,
DATEPART(m,GETDATE()) AS Month,
DATEPART(quarter,GETDATE()) AS Quarter,
DATEPART(dayofyear,GETDATE()) AS daynumber

DATENAME()函數(shù),

與DATEPART不同的地方在于返回字符類型,比如Jan,一月等
語法:

DATENAME(datepart,date)

實例:

SELECT DATENAME(month, getdate()) AS 'Month'

對于中英文切換拌喉,使用如下語句:

set LANGUAGE 'Simplified Chinese'
select  DATENAME(WEEKDAY,getutcdate())

set LANGUAGE 'us_english'
select  DATENAME(WEEKDAY,getutcdate())

日期計算函數(shù)

EOMonth()函數(shù)

EOMonth()函數(shù)可以返回月份的最后一天速那。因此我們可以利用這個函數(shù)求某個月的最后一天與第一天。
語法:

EOMONTH(start_date [,month_to_add])

其中start_date: 有兩種輸入方式尿背,能夠轉(zhuǎn)換為Date的字符串類型 和 date 數(shù)據(jù)類型
month_to_add: 是int 類型端仰,能夠為正整數(shù),負整數(shù)和0田藐,默認值是0荔烧,如果省略吱七,那么使用默認值0,表示月份的偏移量。

--查看當前月的最后一天鹤竭、下一個月的最后一天踊餐、上一個月的最后一天
declare @date date
set @date=getdate()

select EOMONTH(@date) as CurrentMonth_EndDay,
    EOMONTH(@date,1) as NextMonth_EndDay,
    EOMONTH(@date,-1) as LastMonth_EndDay

dateadd()函數(shù)

DATEADD() 函數(shù)在日期中添加或減去指定的時間間隔。
語法:

DATEADD(datepart,number,date)

其中datepart是單位(年臀稚,月吝岭,天等),number是指定的數(shù)值吧寺,date是原始日期
如下例的結(jié)果是當前時間的兩個月后的日期窜管,類型為datetime類型

    SELECT DATEADD(MONTH,2,getdate())

根據(jù)上述兩個函數(shù)我們還可以通過上個月的最后一天+1來獲取每個月第一天

select dateadd(day,1,EOMONTH(getdate(),-1)) as CurrentMonth_startDay

同時也可以通過前面所說的日期拼接函數(shù)與format函數(shù)實現(xiàn)

declare @date date
set @date=getdate()

select DATEFROMPARTS(year(@date),month(@date),1) 

--or

select FORMAT(GETDATE(),'yyyy-MM-01')

DATEDIFF()函數(shù)

DATEDIFF()函數(shù)計算兩個日期之間的間隔,傳回帶正負符號的整數(shù)

語法:

DATEDIFF(datepart,startdate,enddate)

datepart為間隔的單位稚机,可以選擇天幕帆,周,月等赖条。startdate跟enddate為起始時間

實例:

SELECT DATEDIFF(DAY, '2010-10-03','2010-10-04'  )

結(jié)果返回1

構(gòu)造日期的函數(shù)

構(gòu)造日期的函數(shù)有以下幾個:
語法:

    DATEFROMPARTS ( year, month, day )
    DATETIME2FROMPARTS ( year, month, day, hour, minute, seconds, fractions, precision ) 
    DATETIMEOFFSETFROMPARTS ( year, month, day, hour, minute, seconds, fractions, hour_offset, minute_offset, precision )
    TIMEFROMPARTS ( hour, minute, seconds, fractions, precision ) 

傳入對應參數(shù)后即可
其中參數(shù)precision 是指小數(shù)秒的精度失乾,指的是DateTime2(n)、DateTimeOffset(n),Time(n)中的n值纬乍,表示以多少位小數(shù)表示1s仗扬,一般比較少使用

select DATEFROMPARTS ( 2020, 1, 2 )

練習實例

現(xiàn)有一列日期,請根據(jù)日期輸出對應的每周開始與每周結(jié)束日期并格式化蕾额。
例如原始數(shù)據(jù)time_test表:

| date      | 
|-----------|
| 2020-8-4  | 
| 2020-8-5  | 
| 2020-8-6  | 
| 2020-8-12 | 
| 2020-8-8  | 
| 2020-8-12 | 
| 2020-9-15 |

期望的輸出結(jié)果:

| date      | period  |
|-----------|---------|
| 2020-8-4  |0803-0809|
| 2020-8-5  |0803-0809|
| 2020-8-6  |0803-0809|
| 2020-8-12 |0810-0816|
| 2020-8-8  | 0803-0809|
| 2020-8-12 | 0803-0809|
| 2020-9-15 |0810-0816|

其中period的開始為每周周一,結(jié)束日期為每周周日

解答:
先給出代碼

select [date],
format(DATEADD(wk, DATEDIFF(wk,0,DATEADD(dd,-1,[date])), 0),'MMdd')+'-'+format(DATEADD(dd,-1,DATEADD(wk, DATEDIFF(wk,0,DATEADD(dd,6,[date])), 0)),'MMdd') as period
from time_test

從內(nèi)到外解析這一段代碼彼城,我們首先利用datediif(wk,0,date)計算從1900-01-01 到指定日期的周數(shù)诅蝶。之后利用DateAdd函數(shù)在1900-01-01 的基礎(chǔ)上加上剛剛我們計算出的周數(shù),從而得到每周的開始時間募壕。最后通過forma函數(shù)對日期格式化即可得出結(jié)果调炬。

其中在最內(nèi)層有一個DATEADD(dd,-1,[date]),這個是由于我使用的是英文版的SQL server,所以每周是周日開始與周六結(jié)束舱馅,如果使用中文版SQL server,應該就可以直接使[date]列

我的WX公眾號:Romi的雜貨鋪缰泡,歡迎關(guān)注!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末代嗤,一起剝皮案震驚了整個濱河市棘钞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌干毅,老刑警劉巖宜猜,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異硝逢,居然都是意外死亡姨拥,警方通過查閱死者的電腦和手機绅喉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叫乌,“玉大人柴罐,你說我怎么就攤上這事『┘椋” “怎么了革屠?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長膀藐。 經(jīng)常有香客問我屠阻,道長,這世上最難降的妖魔是什么额各? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任国觉,我火速辦了婚禮,結(jié)果婚禮上虾啦,老公的妹妹穿的比我還像新娘麻诀。我一直安慰自己,他們只是感情好傲醉,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布蝇闭。 她就那樣靜靜地躺著,像睡著了一般硬毕。 火紅的嫁衣襯著肌膚如雪呻引。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天吐咳,我揣著相機與錄音逻悠,去河邊找鬼。 笑死韭脊,一個胖子當著我的面吹牛童谒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播沪羔,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼饥伊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蔫饰?” 一聲冷哼從身側(cè)響起琅豆,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎篓吁,沒想到半個月后趋距,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡越除,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年节腐,在試婚紗的時候發(fā)現(xiàn)自己被綠了外盯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡翼雀,死狀恐怖饱苟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情狼渊,我是刑警寧澤箱熬,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站狈邑,受9級特大地震影響城须,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜米苹,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一糕伐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蘸嘶,春花似錦良瞧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至况增,卻和暖如春赞庶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背澳骤。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工歧强, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宴凉。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像表悬,于是被迫代替她去往敵國和親弥锄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355