Sql server 在T-SQL中将datetime转换为指定格式的float
我需要将日期时间转换为以下格式的浮点:Sql server 在T-SQL中将datetime转换为指定格式的float,sql-server,tsql,datetime,Sql Server,Tsql,Datetime,我需要将日期时间转换为以下格式的浮点: YYYY.[fractionalPart] (示例4/1/2020 3:40:00 AM应转换为2020.249051) 在Excel中,这非常简单 YEAR(myDate) + YEARFRAC(startOfYear, myDate, 1) 但我在t-SQL中找不到类似的简单方法来实现这一点 我编写了以下标量函数来完成这项工作: ALTER function [dbo].[DecimalDate] (@Datetime datetime) RETU
YYYY.[fractionalPart]
(示例4/1/2020 3:40:00 AM
应转换为2020.249051
)
在Excel中,这非常简单
YEAR(myDate) + YEARFRAC(startOfYear, myDate, 1)
但我在t-SQL中找不到类似的简单方法来实现这一点
我编写了以下标量函数来完成这项工作:
ALTER function [dbo].[DecimalDate] (@Datetime datetime)
RETURNS FLOAT
AS
BEGIN
DECLARE @yearPart int
DECLARE @secondsPart float --fractional portion of the year, in seconds
DECLARE @secondsFullYear float --total number of seconds in year
DECLARE @FirstDayOfYear Date
Set @yearPart = DATEPART(yy,@Datetime)
Set @FirstDayOfYear = CONVERT(Date, CAST(@yearPart AS varchar)) -- [alternative:] DATEADD(yy, DATEDIFF(yy,0,@Datetime), 0)
SET @secondsPart = datediff(second,@FirstDayOfYear,@Datetime)
SET @secondsFullYear = datediff(second,@FirstDayOfYear, DATEADD(yy, 1, @FirstDayOfYear))
RETURN (SELECT @yearPart + @secondsPart/@secondsFullYear AS DecimalDate )
END
…但这比我希望的要慢,而且对于这么简单的任务来说,它似乎太复杂了。(如果可以的话,它肯定会简化事情!)
您的SQL专家有什么建议吗?我不知道这有多好,但它比较短:
SELECT CAST(DATEDIFF(s, @d, DATEFROMPARTS(YEAR(@d), 1, 1)) as FLOAT) /
DATEDIFF(s, DATEFROMPARTS(YEAR(@d) + 1, 1, 1), DATEFROMPARTS(YEAR(@d), 1, 1)) +
YEAR(@d)
()我不知道这有多好,但它比较短:
SELECT CAST(DATEDIFF(s, @d, DATEFROMPARTS(YEAR(@d), 1, 1)) as FLOAT) /
DATEDIFF(s, DATEFROMPARTS(YEAR(@d) + 1, 1, 1), DATEFROMPARTS(YEAR(@d), 1, 1)) +
YEAR(@d)
()我想这会稍微快一点:
ALTER FUNCTION [dbo].[DecimalDate](@DateTime datetime)
RETURNS FLOAT
AS
BEGIN
DECLARE @year INT
DECLARE @daysInYear INT
SET @year = DATEPART(year, @DateTime)
SET @daysInYear = 337 + DATEPART(DAY, EOMONTH(DATEFROMPARTS(@year, 2, 1)))
RETURN @year + (DATEPART(DAYOFYEAR, @DateTime) - 1 + (DATEDIFF(second, CONVERT(DATE, @DateTime), @DateTime)/86400.0) ) / @daysInYear
END
我怀疑这会稍微快一点:
ALTER FUNCTION [dbo].[DecimalDate](@DateTime datetime)
RETURNS FLOAT
AS
BEGIN
DECLARE @year INT
DECLARE @daysInYear INT
SET @year = DATEPART(year, @DateTime)
SET @daysInYear = 337 + DATEPART(DAY, EOMONTH(DATEFROMPARTS(@year, 2, 1)))
RETURN @year + (DATEPART(DAYOFYEAR, @DateTime) - 1 + (DATEDIFF(second, CONVERT(DATE, @DateTime), @DateTime)/86400.0) ) / @daysInYear
END
主要问题不在于代码本身,而是标量函数——在SQL Server中,标量函数的速度往往较慢 除了将代码重写为尽可能内联外,您还可以使用一些其他技巧,例如下面我的代码中所示的技巧:
create function dbo.YearFraction (
@dt datetime
)
/*
User-defined substitution of the Excel' YEARFRAC() function.
20150915, RFW - initial release
*/
returns float with schemabinding, returns null on null input as begin
return (
select
year(@dt) + cast(datediff(second, c.FDY, @dt) as float) / datediff(second, c.FDY, dateadd(year, 1, c.FDY))
from (
select cast(cast(year(@dt) as varchar) + '0101' as datetime) as [FDY]
) c
);
end;
go
主要问题不在于代码本身,而是标量函数——在SQL Server中,标量函数的速度往往较慢 除了将代码重写为尽可能内联外,您还可以使用一些其他技巧,例如下面我的代码中所示的技巧:
create function dbo.YearFraction (
@dt datetime
)
/*
User-defined substitution of the Excel' YEARFRAC() function.
20150915, RFW - initial release
*/
returns float with schemabinding, returns null on null input as begin
return (
select
year(@dt) + cast(datediff(second, c.FDY, @dt) as float) / datediff(second, c.FDY, dateadd(year, 1, c.FDY))
from (
select cast(cast(year(@dt) as varchar) + '0101' as datetime) as [FDY]
) c
);
end;
go
它似乎比我的要快30%(因为它足够短,可以内联),而且比我的要干净得多。非常感谢。它似乎比我的要快30%(因为它足够短,可以内联),而且比我的要干净得多。非常感谢。