当前位置: 首页 > 科技观察

说说SQL高级日期函数

时间:2023-03-20 13:19:47 科技观察

通常我们在计算时间或者计算日期的时候都会用到一些日期函数,大部分都是比较常用的,比如YEAR(),MONTH(),DATEADD()等,今天就来向您解释一些更高级的日期功能。测试环境SQLServer2017@@DATEFIRST函数是针对特定会话的,该函数返回SETDATEFIRST的当前值。语法@@DATEFIRST注意:SETDATEFIRSTn指定一周的第一天(星期日、星期一、星期二等)。n的取值范围为1到7。例如,我们指定周日为一周的第一天,那么今天(2021-12-08)的@@DATEFIRST将返回1。具体如下:SETDATEFIRST1;--表示周一是一周的第一天SELECT@@DATEFIRST;--返回DATEFIRST的值结果:很多人可能认为这个函数作用不大,但实际上对于设置星期几的第一天非常有用。美国以行星日为一周的第一天,而我国通常以星期一为一周的第一天。比如我想知道上周第3天的销量,你需要把上周的这一天定义为第1天,才能进一步计算第3天的销量。系统时间获取系统时间有一套函数,比较常见的是GETDATE函数,这些函数也都有。SELECTSYSDATETIME()SELECTSYSDATETIMEOFFSET()SELECTSYSUTCDATETIME()SELECTCURRENT_TIMESTAMPSELECTGETDATE()SELECTGETUTCDATE()结果:包括UTC在内的系统时间为世界时,其他为当前时区时间。注意:CURRENT_TIMESTAMP等同于GETDATE()函数。DATEADD将指定的数字值(作为有符号整数)添加到输入日期值的指定日期部分并返回修改后的值。语法DATEADD(datepart,number,date)其中datepart参数由系统定义,具体参数列表如下:datepart缩写year,yyyyquarterqq,qmonthmm,dayofmyeardy,ydaydd,dweekwk,wwweekdw,whourhhminutemi,nsecondss,s毫秒mssubtlemcsnanosecondns示例查询上个月今天,下个月今天SELECTDATEADD(month,-1,'20211208');SELECTDATEADD(月,1,'20211208');结果:DATEDIFF函数返回在指定开始日期和结束日期之间交叉的指定日期部分边界的计数(作为有符号整数值)。语法DATEDIFF(datepart,startdate,enddate)注意:返回值是startdate和enddate之间的int差值,由datepart设置的边界表示。示例计算去年第一天和今天之间的天数SELECTDATEDIFF(DAY,'20200101','20211208')结果:DATEFROMPARTS此函数返回映射到指定年、月和日值的日期值。语法DATEFROMPARTS(year,month,day)注意:DATEFROMPARTS返回一个日期值,日期部分设置为指定的年月日,时间部分设置为默认值。DATEFROMPARTS为无效参数抛出错误。如果至少一个必需参数具有NULL值,则DATEFROMPARTS返回NULL。此函数在SQLServer2012(11.x)和更高版本的服务器上执行远程处理。它无法在SQLServer2012(11.x)之前的服务器上执行远程处理。该示例通过指定特定年月日返回今天的日期:SELECTDATEFROMPARTS(2021,12,8)ASResult;结果DATENAME函数返回一个字符串,表示指定日期的指定日期部分。语法DATENAME(datepart,date)示例SELECTDATENAME(year,getdate())'Year',DATENAME(month,getdate())'Month',DATENAME(day,getdate())'Day',DATENAME(weekday,getdate())'工作日';结果:通过这个函数,我们可以知道具体某一天的年、月、日、周等具体信息。特别是在进行数据分组统计时经常使用。DATEPART函数返回一个整数,表示指定日期的指定日期部分。语法DATEPART(datepart,date)示例SELECTDATEPART(year,getdate())'Year',DATEPART(month,getdate())'Month',DATEPART(day,getdate())'Day',DATEPART(weekday,getdate())'工作日';结果:细心的同学可能会发现DATEPART和DATENAME有很多相似之处,但是请注意它们返回的类型是不同的。DATEPART返回数值类型,DATENAME返回字符串类型。EOMONTH函数返回包含指定日期(带有可选偏移量)的月份的最后一天dateDATETIME='20211208';SELECTEOMONTH(@date)ASResult;GO结果:添加偏移量参数month_to_add例如返回下个月的最后一天:DECLARE@dateDATETIME='20211208';SELECTEOMONTH(@date,1)作为结果;GO结果:ISDATE函数如果表达式是有效的日期、时间或日期时间值,则返回1;否则返回0。如果表达式是datetime2值,ISDATE返回0。语法ISDATE(expression)判断今天(2021-12-08)是否为合法日期的例子IFISDATE('2021-12-08')=1SELECT'legaldate'ResultELSESELECT'invaliddate'Result;结果:是有兴趣的同学可以尝试判断'2022-02-30'是否合法。实际应用1.本月第一天SELECTDATEADD(mm,DATEDIFF(mm,0,getdate()),0)--2021-12-0100:00:00.0002,周一SELECTDATEADD(wk,DATEDIFF本周的(wk,0,getdate()),0)--2021-12-0600:00:00.0003,今年的第一天SELECTDATEADD(yy,DATEDIFF(yy,0,getdate()),0)--2021-01-0100:00:00.0004,下一季度的第一天SELECTDATEADD(qq,DATEDIFF(qq,-1,getdate()),0)--2021-01-0100:00:00.0005,最后一个月的最后一天SELECTDATEADD(dd,-DAY(getdate()),getdate())--2021-11-3020:14:21.8506,一年的最后一天SELECTDATEADD(year,DATEDIFF(year,0,DATEADD(year,1,getdate())),-1)--2021-12-3100:00:00.0007,去年同一天SELECTDATEADD(YEAR,-1,GETDATE())--2020-12-0820:19:05.987