SQL Server 2012:DATEDIFF 函数以年、日、月表示
SQL Server 2012 : DATEDIFF function in terms of years, days and months
我在 SQL Server 2012 中使用 DATEDIFF
函数。我有两个日期,2015-01-01
和 current_date
。我需要 DATEDIFF
这两个日期之间的 年、月和日 。以下是我的陈述:
SELECT DATEDIFF(YY, '2015-01-01', GETDATE()) AS 'Years'
SELECT DATEDIFF(MM, '2015-01-01', GETDATE()) AS 'Months'
SELECT DATEDIFF(DD, '2015-01-01', GETDATE()) AS 'Days'
我得到的结果是:年 = 3,月 = 46,天 = 1416
为什么在几个月和几天内增加了一年?
DATEDIFF()
测量两个 date/time 值之间的时间边界数。
因此,对于 year
,它测量年份翻转的次数(即新的一年开始)。
对于 month
,它测量月份翻转的次数(即新月份开始)。
对于 day
,它测量一天翻转的次数(即新的一天开始)。
这些都是相互独立的
我建议您不要尝试获取years/months/days中的值。这是一个难题。 2 月 28 日至 3 月 31 日期间 months/days 的数量是多少? 1 月 31 日至 2 月 28 日之间? 1 月 31 日至 3 月 31 日之间?他们不加起来,使这成为一个难题。
也许有点矫枉过正,但如果您对 TVF 持开放态度
例子
Declare @YourTable table (SomeDate date)
Insert Into @YourTable values
('2015-01-01')
Select A.SomeDate
,B.*
From @YourTable A
Cross Apply [dbo].[tvf-Date-Elapsed](SomeDate,GetDate()) B
Returns
SomeDate Years Months Days Hours Minutes Seconds
2015-01-01 3 10 16 8 22 40
感兴趣的函数
CREATE FUNCTION [dbo].[tvf-Date-Elapsed] (@D1 DateTime,@D2 DateTime)
Returns Table
Return (
with cteBN(N) as (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cteRN(R) as (Select Row_Number() Over (Order By (Select NULL))-1 From cteBN a,cteBN b,cteBN c),
cteYY(N,D) as (Select Max(R),Max(DateAdd(YY,R,@D1))From cteRN R Where DateAdd(YY,R,@D1)<=@D2),
cteMM(N,D) as (Select Max(R),Max(DateAdd(MM,R,D)) From (Select Top 12 R From cteRN Order By 1) R, cteYY P Where DateAdd(MM,R,D)<=@D2),
cteDD(N,D) as (Select Max(R),Max(DateAdd(DD,R,D)) From (Select Top 31 R From cteRN Order By 1) R, cteMM P Where DateAdd(DD,R,D)<=@D2),
cteHH(N,D) as (Select Max(R),Max(DateAdd(HH,R,D)) From (Select Top 24 R From cteRN Order By 1) R, cteDD P Where DateAdd(HH,R,D)<=@D2),
cteMI(N,D) as (Select Max(R),Max(DateAdd(MI,R,D)) From (Select Top 60 R From cteRN Order By 1) R, cteHH P Where DateAdd(MI,R,D)<=@D2),
cteSS(N,D) as (Select Max(R),Max(DateAdd(SS,R,D)) From (Select Top 60 R From cteRN Order By 1) R, cteMI P Where DateAdd(SS,R,D)<=@D2)
Select [Years] = cteYY.N
,[Months] = cteMM.N
,[Days] = cteDD.N
,[Hours] = cteHH.N
,[Minutes] = cteMI.N
,[Seconds] = cteSS.N
--,[Elapsed] = Format(cteYY.N,'0000')+':'+Format(cteMM.N,'00')+':'+Format(cteDD.N,'00')+' '+Format(cteHH.N,'00')+':'+Format(cteMI.N,'00')+':'+Format(cteSS.N,'00')
From cteYY,cteMM,cteDD,cteHH,cteMI,cteSS
)
--Max 1000 years
--Select * from [dbo].[tvf-Date-Elapsed] ('1991-09-12 21:00:00.000',GetDate())
--Select * from [dbo].[tvf-Date-Elapsed] ('2017-01-01 20:30:15','2018-02-05 22:58:35')
我对@JohnCappelletti 启发性回答的看法
CREATE FUNCTION [dbo].[tvf_interval_parts] (@start DateTime, @cease DateTime)
Returns Table
RETURN
SELECT
*
FROM
(
SELECT
months / 12 AS years,
months % 12 AS months
FROM
(
SELECT
CASE WHEN DATEADD(MONTH, months, @start) > @cease THEN months - 1
WHEN DATEADD(MONTH, months, @start) = DATEADD(MONTH, months, @start-1) THEN months - 1
ELSE months END AS months
FROM
(
SELECT DATEDIFF(MONTH, @start, @cease) AS months
)
provisional
)
adjusted
)
interim
CROSS APPLY
(
SELECT
milliseconds / (24 * 60 * 60 * 1000) AS days,
milliseconds % (24 * 60 * 60 * 1000) / ( 60 * 60 * 1000) AS hours,
milliseconds % ( 60 * 60 * 1000) / ( 60 * 1000) AS minutes,
milliseconds % ( 60 * 1000) / ( 1000) AS seconds,
milliseconds % ( 1000) AS milliseconds
FROM
(
SELECT DATEDIFF_BIG(millisecond, DATEADD(MONTH, 12 * years + months, @start), @cease) AS milliseconds
)
provisional
)
remainder
此处的用法示例:https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=47b2d437c4cea78d182ce0f63772ef38
我在 SQL Server 2012 中使用 DATEDIFF
函数。我有两个日期,2015-01-01
和 current_date
。我需要 DATEDIFF
这两个日期之间的 年、月和日 。以下是我的陈述:
SELECT DATEDIFF(YY, '2015-01-01', GETDATE()) AS 'Years'
SELECT DATEDIFF(MM, '2015-01-01', GETDATE()) AS 'Months'
SELECT DATEDIFF(DD, '2015-01-01', GETDATE()) AS 'Days'
我得到的结果是:年 = 3,月 = 46,天 = 1416
为什么在几个月和几天内增加了一年?
DATEDIFF()
测量两个 date/time 值之间的时间边界数。
因此,对于 year
,它测量年份翻转的次数(即新的一年开始)。
对于 month
,它测量月份翻转的次数(即新月份开始)。
对于 day
,它测量一天翻转的次数(即新的一天开始)。
这些都是相互独立的
我建议您不要尝试获取years/months/days中的值。这是一个难题。 2 月 28 日至 3 月 31 日期间 months/days 的数量是多少? 1 月 31 日至 2 月 28 日之间? 1 月 31 日至 3 月 31 日之间?他们不加起来,使这成为一个难题。
也许有点矫枉过正,但如果您对 TVF 持开放态度
例子
Declare @YourTable table (SomeDate date)
Insert Into @YourTable values
('2015-01-01')
Select A.SomeDate
,B.*
From @YourTable A
Cross Apply [dbo].[tvf-Date-Elapsed](SomeDate,GetDate()) B
Returns
SomeDate Years Months Days Hours Minutes Seconds
2015-01-01 3 10 16 8 22 40
感兴趣的函数
CREATE FUNCTION [dbo].[tvf-Date-Elapsed] (@D1 DateTime,@D2 DateTime)
Returns Table
Return (
with cteBN(N) as (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cteRN(R) as (Select Row_Number() Over (Order By (Select NULL))-1 From cteBN a,cteBN b,cteBN c),
cteYY(N,D) as (Select Max(R),Max(DateAdd(YY,R,@D1))From cteRN R Where DateAdd(YY,R,@D1)<=@D2),
cteMM(N,D) as (Select Max(R),Max(DateAdd(MM,R,D)) From (Select Top 12 R From cteRN Order By 1) R, cteYY P Where DateAdd(MM,R,D)<=@D2),
cteDD(N,D) as (Select Max(R),Max(DateAdd(DD,R,D)) From (Select Top 31 R From cteRN Order By 1) R, cteMM P Where DateAdd(DD,R,D)<=@D2),
cteHH(N,D) as (Select Max(R),Max(DateAdd(HH,R,D)) From (Select Top 24 R From cteRN Order By 1) R, cteDD P Where DateAdd(HH,R,D)<=@D2),
cteMI(N,D) as (Select Max(R),Max(DateAdd(MI,R,D)) From (Select Top 60 R From cteRN Order By 1) R, cteHH P Where DateAdd(MI,R,D)<=@D2),
cteSS(N,D) as (Select Max(R),Max(DateAdd(SS,R,D)) From (Select Top 60 R From cteRN Order By 1) R, cteMI P Where DateAdd(SS,R,D)<=@D2)
Select [Years] = cteYY.N
,[Months] = cteMM.N
,[Days] = cteDD.N
,[Hours] = cteHH.N
,[Minutes] = cteMI.N
,[Seconds] = cteSS.N
--,[Elapsed] = Format(cteYY.N,'0000')+':'+Format(cteMM.N,'00')+':'+Format(cteDD.N,'00')+' '+Format(cteHH.N,'00')+':'+Format(cteMI.N,'00')+':'+Format(cteSS.N,'00')
From cteYY,cteMM,cteDD,cteHH,cteMI,cteSS
)
--Max 1000 years
--Select * from [dbo].[tvf-Date-Elapsed] ('1991-09-12 21:00:00.000',GetDate())
--Select * from [dbo].[tvf-Date-Elapsed] ('2017-01-01 20:30:15','2018-02-05 22:58:35')
我对@JohnCappelletti 启发性回答的看法
CREATE FUNCTION [dbo].[tvf_interval_parts] (@start DateTime, @cease DateTime)
Returns Table
RETURN
SELECT
*
FROM
(
SELECT
months / 12 AS years,
months % 12 AS months
FROM
(
SELECT
CASE WHEN DATEADD(MONTH, months, @start) > @cease THEN months - 1
WHEN DATEADD(MONTH, months, @start) = DATEADD(MONTH, months, @start-1) THEN months - 1
ELSE months END AS months
FROM
(
SELECT DATEDIFF(MONTH, @start, @cease) AS months
)
provisional
)
adjusted
)
interim
CROSS APPLY
(
SELECT
milliseconds / (24 * 60 * 60 * 1000) AS days,
milliseconds % (24 * 60 * 60 * 1000) / ( 60 * 60 * 1000) AS hours,
milliseconds % ( 60 * 60 * 1000) / ( 60 * 1000) AS minutes,
milliseconds % ( 60 * 1000) / ( 1000) AS seconds,
milliseconds % ( 1000) AS milliseconds
FROM
(
SELECT DATEDIFF_BIG(millisecond, DATEADD(MONTH, 12 * years + months, @start), @cease) AS milliseconds
)
provisional
)
remainder
此处的用法示例:https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=47b2d437c4cea78d182ce0f63772ef38