第四十三章 SQL函数 DATEDIFF
日期/时间函数,返回两个日期之间指定日期部分的整数差。
大纲
DATEDIFF(datepart,startdate,enddate)
参数
datepart
– 日期或时间部分的名称(或缩写)。这个名称可以用大写或小写来指定,有或没有引号。datepart
可以指定为文字或主机变量。startdate
– 间隔的开始日期/时间。可以是各种标准格式的日期、时间或日期时间。enddate
– 间隔的结束日期/时间。可以是各种标准格式的日期、时间或日期时间。从enddate
中减去startdate
,以确定两个日期之间的日期部分间隔。
描述
DATEDIFF
函数返回两个指定日期之间指定日期部分差的整数。日期范围从开始日期开始,到结束日期结束。(如果enddate
早于startdate
,DATEDIFF
将返回一个负整数值。)
DATEDIFF
返回startdate
和enddate
之间指定单位的总数。例如,两个日期时间值之间的分钟数计算日期部分和时间部分,并为每一天的差异增加1440
分钟。DATEDIFF
返回开始日期和结束日期之间跨越的指定日期部分边界的计数。例如,指定连续年份的任意两个日期(例如2018-09-23
和2019-01-01
)返回的年份DATEDIFF
为1,而不管这两个日期之间的实际持续时间是大于还是小于365
天。同样,12:23:59
和12:24:05
之间的分钟数是1,尽管实际上只有6
秒将两个值分开。
请注意,DATEDIFF
是为Sybase和Microsoft SQL Server兼容性而提供的。使用TIMESTAMPDIFF ODBC
标量函数可以执行类似的时间/日期比较操作。
也可以使用DATEDIFF()
方法调用从ObjectScript
调用此函数:
$SYSTEM.SQL.Functions.DATEDIFF(datepart,startdate,enddate)
为DATEDIFF()
方法指定无效的datepart
、startdate
或enddate
会生成< ZDDIF >
错误。
Datepart 参数
日期部分参数可以是下列日期/时间组件之一,可以是全名(日期部分列)或其缩写(缩写列)。这些datepart
组件名称和缩写不区分大小写。
Date Part | Abbreviations |
---|---|
year | yyyy, yy |
month | mm, m |
week | wk, ww |
weekday | dw |
day | dd, d |
dayofyear | dy |
hour | hh |
minute | mi, n |
second | ss, s |
millisecond | ms |
microsecond | mcs |
nanosecond | ns |
weekday
和dayofyear datepart
值在功能上与day datepart
值相同。
DATEDIFF
和TIMESTAMPDIFF
不处理季度(间隔3
个月)。
如果指定包含分数秒的开始日期和结束日期,DATEDIFF
将以分数秒的整数形式返回差值,如下例所示:
SELECT DATEDIFF('ms','64701,56670.10','64701,56670.27'), /* returns 170 */
DATEDIFF('ms','64701,56670.1111','64701,56670.27222') /* returns 161 */
datepart
可以指定为带引号的字符串或不带引号的字符串。这些语法变体执行略有不同的操作:
- Quotes:
DATEDIFF('month','2018-02-25',$HOROLOG)
:在创建缓存查询时,datepart
被视为文字。SQL执行文字替换。这将产生一个更容易重用的缓存查询。 - 无引号:
DATEDIFF(month,'2018-02-25',$HOROLOG)
:创建缓存查询时,datepart
被视为关键字。没有文字替换。这将生成更具体的缓存查询。
日期表达式格式
startdate
和enddate
参数可以采用不同的数据类型格式。
startdate
和enddate
参数可以采用以下任何格式:
%Date
逻辑值(+$H
),也称为$HOROLOG
格式。%PosixTime
(%Library.PosixTime
。逻辑值(编码的64位有符号整数)%TimeStamp
(%Library.TimeStamp
)逻辑值(YYYY-MM-DD HH:MM:SS。FFF
),也称为ODBC
格式。%String
(或兼容)值。
%String
(或compatible
)值可以是以下任何一种格式,可以包含或省略小数秒:
-
99999、99999
($HOROLOG
格式)。
$HOROLOG
特殊变量不返回小数秒。
但是,可以使用$HOROLOG
格式指定一个包含分数秒的值:99999,99999.999
-
Sybase/SQL-Server-date Sybase/SQL-Server-time
-
Sybase/SQL-Server-time Sybase/SQL-Server-date
-
Sybase/SQL-Server-date (default time is 00:00:00)
-
Sybase/SQL-Server-time (default date is 01/01/1900)
Sybase/SQL-Server-date是以下五种格式之一:
mm/dd/[yy]yy dd Mmm[mm][,][yy]yy dd [yy]yy Mmm[mm] yyyy Mmm[mm] dd yyyy [dd] Mmm[mm]
在第一种语法格式中,分隔符可以是斜杠(/
)、连字符(-
)或句点(.
)。
Sybase/SQL-Server-time表示以下三种格式之一:
HH:MM[:SS[:FFF]][{AM|PM}] HH:MM[:SS[.FFF]] HH['']{AM|PM}
Years
如果年份以两位数字表示,或者日期被完全省略, IRIS会检查滑动窗口来解释日期。
系统范围内滑动窗口的默认值是1900
;
因此,在默认情况下,两位数的年份被认为是在20世纪。
如下示例所示:
SELECT DATEDIFF('year','10/11/14','02/22/2018'),
DATEDIFF('year','12:00:00','2018-02-22 12:00:00')
分数秒
DATEDIFF
返回以毫秒(3位整数)、微秒(6位整数)或纳秒(9位整数)表示的小数秒,而不管startdate
和enddate
中的小数位数精度是多少。
如下示例所示:
SELECT DATEDIFF('ms','12:00:00.1','12:00:00.2'),
DATEDIFF('ms','12:00:00.10009','12:00:00.20007')
一些NLS区域设置将分数分隔符指定为逗号(欧洲的用法),而不是句号。
如果当前区域设置是这些区域设置之一,DATEDIFF
接受句号或逗号作为本地日期格式的秒分隔符。
对于$HOROLOG
格式的日期或ODBC
格式的日期,不能使用逗号作为小数秒分隔符。
尝试这样做会生成一个SQLCODE -8
。
无论当前的NLS语言环境是什么,这两种格式都需要一段时间。
时间差异与时间格式无关
DATEDIFF
返回以秒和毫秒为单位的时间差,即使当前进程的TimeFormat
被设置为不返回秒。
如下示例所示:
ClassMethod DateDiff()
{
s tfmt = ##class(%SYS.NLS.Format).GetFormatItem("TimeFormat")
d ##class(%SYS.NLS.Format).SetFormatItem("TimeFormat",1)
w "datetime values (with seconds) are: ",!,
$ZDATETIME("64701,56670.10",1,-1)," ",$ZDATETIME("64701,56673.27",1,-1),!
&sql(SELECT DATEDIFF('ss','64701,56670.10','62871,56673.27') INTO :x)
w "DATEDIFF number of seconds is: ",x,!!
d ##class(%SYS.NLS.Format).SetFormatItem("TimeFormat",2)
w "datetime values (without seconds) are: ",!,
$ZDATETIME("64701,56670.10",1,-1)," ",$ZDATETIME("64701,56673.27",1,-1),!
&sql(SELECT DATEDIFF('ss','64701,56670.10','64701,56673.27') INTO :x)
w "DATEDIFF number of seconds is: ",x,!
d ##class(%SYS.NLS.Format).SetFormatItem("TimeFormat",tfmt)
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).DateDiff()
datetime values (with seconds) are:
02/22/2018 15:44:30 02/22/2018 15:44:33
DATEDIFF number of seconds is: -158111996.83
datetime values (without seconds) are:
02/22/2018 15:44 02/22/2018 15:44
DATEDIFF number of seconds is: 3.17
范围和值检查
DATEDIFF
对输入值执行以下检查:
- 在执行任何
DATEDIFF
操作之前,开始日期和结束日期的所有指定部分必须是有效的。 - 日期字符串必须完整,格式正确,包含适当数量的元素和每个元素的数字,以及适当的分隔符。
年必须指定为四位数字。
如果省略输入值的日期部分,DATEDIFF
默认为' 1900-01-01 '
。
无效的日期值将导致SQLCODE -8
错误。 - 日期和时间值必须在有效范围内。
年龄:0001
到9999
。
月份:1 - 12
个月。
天数:1 - 31
天。
营业时间:00
至23
。
分钟:0
到59
分钟。
秒:0 ~ 59
。
一个月中的天数必须与月和年相匹配。
例如,日期“02-29”
仅在指定的年份为闰年时有效。
无效的日期值将导致SQLCODE -8
错误。 - 小于
10
(月和日)的日期值可以包括或省略前导零。
不允许使用其他非规范整数值。
因此,Day
值为“07”
或“7”
是有效的,但“007”
、“7.0”
或“7a”
无效。 - 时间值可以全部或部分省略。
如果startdate
或enddate
指定了一个不完整的时间,则为未指定的部分提供0
。 - 小于
10
的小时值必须包含前导零。
省略前导零将导致SQLCODE -8
错误。
错误处理
- 在
Embedded SQL
中,如果指定无效的datepart
作为输入变量,则会发出SQLCODE -8
错误码。
如果将无效的日期部分指定为文字,则会发生<SYNTAX>
错误。
如果将无效的开始日期或结束日期指定为输入变量或文字,则会发出SQLCODE -8
错误码。 - 在动态SQL中,如果您提供了无效的日期部分、开始日期或结束日期,则
DATEDIFF
函数将返回一个NULL
值。
没有发出SQLCODE
错误。
示例
下面的例子返回353
,因为两个时间戳之间有353
天(D):
SELECT DATEDIFF(D,'2018-01-01 00:00:00','2018-12-20 12:00:00')
353
在下面的示例中,每个DATEDIFF
返回1
,因为日期的年份部分相差1。
日期之间的实际持续时间不被考虑:
SELECT DATEDIFF('yyyy','1910-08-21','1911-08-21') AS ExactYear,
DATEDIFF('yyyy','1910-06-30','1911-01-01') AS HalfYear,
DATEDIFF('yyyy','1910-01-01','1911-12-31') AS Nearly2Years,
DATEDIFF('yyyy','1910-12-31 11:59:59','1911-01-01 00:00:00') AS NewYearSecond
1 1 1 1
注意,上面的例子使用了日期部分的缩写。
但是,你可以指定全名,如下例所示:
SELECT DATEDIFF('year','2017-09-10 13:19:00','2018-12-20 00:00:00')
1
下面的嵌入式SQL示例使用主机变量执行与前面示例相同的DATEDIFF
操作:
ClassMethod DateDiff1()
{
s x="year"
s date1="2017-09-10 13:19:00"
s date2="2018-12-20 00:00:00"
&sql(SELECT DATEDIFF(:x,:date1,:date2)
INTO :diff)
w diff
}
1
下面的例子使用WHERE
子句中的DATEDIFF
来选择上周入院的患者:
SELECT Name,DateOfAdmission FROM Sample.Patients WHERE DATEDIFF(D,DateOfAdmission,$HOROLOG) <= 7
下面的例子使用了一个子查询来返回那些个人的出生日期距当前日期不超过1500
天的记录:
SELECT Name,Age,DOB
FROM (SELECT Name,Age,DOB, DATEDIFF('dy',DOB,$HOROLOG) AS DaysTo FROM Sample.Person)
WHERE DaysTo <= 1500
ORDER BY Age
今天的文章第四十三章 SQL函数 DATEDIFF分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/32500.html