如何用年、月、日、时、分、秒和毫秒计算T-SQL中的年龄
这个问题是这个问题的延伸 我试图扩展Dane的答案,但结果有点问题如何用年、月、日、时、分、秒和毫秒计算T-SQL中的年龄,sql,sql-server,Sql,Sql Server,这个问题是这个问题的延伸 我试图扩展Dane的答案,但结果有点问题 DECLARE @dateFrom DATETIME DECLARE @dateTo DATETIME DECLARE @tmpdate DATETIME DECLARE @years INT DECLARE @months INT DECLARE @days INT DECLARE @hours INT DECLARE @minutes INT DECLARE @seconds INT DECLARE @millisecon
DECLARE @dateFrom DATETIME
DECLARE @dateTo DATETIME
DECLARE @tmpdate DATETIME
DECLARE @years INT
DECLARE @months INT
DECLARE @days INT
DECLARE @hours INT
DECLARE @minutes INT
DECLARE @seconds INT
DECLARE @milliseconds INT
SELECT @dateFrom = '2011-01-01 11:24:38:100'
SELECT @dateTo = '2012-01-01 11:24:38:110'
SELECT @tmpdate = @dateFrom
SELECT @years = DATEDIFF(yy, @tmpdate, @dateTo)
- CASE WHEN (MONTH(@dateFrom) > MONTH(@dateTo)) OR (MONTH(@dateFrom) = MONTH(@dateTo) AND DAY(@dateFrom) > DAY(@dateTo))
THEN 1
ELSE 0
END
SELECT @tmpdate = DATEADD(yy, @years, @tmpdate)
SELECT @months = DATEDIFF(mm, @tmpdate, @dateTo) - CASE WHEN DAY(@dateFrom) > DAY(@dateTo) THEN 1 ELSE 0 END
SELECT @tmpdate = DATEADD(mm, @months, @tmpdate)
SELECT @days = DATEDIFF(dd, @tmpdate, @dateTo)
SELECT @tmpdate = DATEADD(dd, @days, @tmpdate)
SELECT @hours = DATEDIFF(hh, @tmpdate, @dateTo)
SELECT @tmpdate = DATEADD(hh, @hours, @tmpdate)
SELECT @minutes = DATEDIFF(mi, @tmpdate, @dateTo)
SELECT @tmpdate = DATEADD(mi, @minutes, @tmpdate)
SELECT @seconds = DATEDIFF(ss, @tmpdate, @dateTo)
SELECT @tmpdate = DATEADD(ss, @seconds, @tmpdate)
SELECT @milliseconds = DATEDIFF(ms, @tmpdate, @dateTo)
SELECT
@years AS [years]
, @months AS [months]
, @days AS [days]
, @hours AS [hours]
, @minutes AS [minutes]
, @seconds AS [seconds]
, @milliseconds AS [milliseconds]
结果是:
years months days hours minutes seconds milliseconds
1 0 0 0 0 0 10
years months days hours minutes seconds milliseconds
0 11 30 -1 -1 -1 -10
但当我跑步时:
SELECT @dateFrom = '2011-01-02 11:24:38:110'
SELECT @dateTo = '2012-01-01 10:23:37:100'
结果是:
years months days hours minutes seconds milliseconds
1 0 0 0 0 0 10
years months days hours minutes seconds milliseconds
0 11 30 -1 -1 -1 -10
谢谢你的帮助 答案是正确的,但它显示为负值。您需要使用abs返回正值
SELECT
@years AS [years]
, abs(@months) AS [months]
, abs(@days) AS [days]
, abs(@hours) AS [hours]
, abs(@minutes) AS [minutes]
, abs(@seconds) AS [seconds]
, abs(@milliseconds) AS [milliseconds]
答案是正确的,但它显示为负值。您需要使用abs返回正值
SELECT
@years AS [years]
, abs(@months) AS [months]
, abs(@days) AS [days]
, abs(@hours) AS [hours]
, abs(@minutes) AS [minutes]
, abs(@seconds) AS [seconds]
, abs(@milliseconds) AS [milliseconds]
因为@dateFrom中的日期晚于@dateTo中的日期,所以您会得到这些负值,我认为您最好在流程开始之前交换这些值,这样您就不需要在流程结束后重新格式化变量:
DECLARE @auxDate DATETIME
IF (@dateFrom>@dateTo)
BEGIN
SET @auxDate = @dateFrom
SET @dateFrom = @dateTo
SET @dateTo = @auxDate
END
-- Your code..
因为@dateFrom中的日期晚于@dateTo中的日期,所以您会得到这些负值,我认为您最好在流程开始之前交换这些值,这样您就不需要在流程结束后重新格式化变量:
DECLARE @auxDate DATETIME
IF (@dateFrom>@dateTo)
BEGIN
SET @auxDate = @dateFrom
SET @dateFrom = @dateTo
SET @dateTo = @auxDate
END
-- Your code..
请看我回答的问题。
它处理的情况如下: @dateFrom='2014-04-2413:59:00'
@日期='2014-04-2414:01:00'
您的代码为这些值返回了错误的日期。请查看我回答的问题。
CREATE FUNCTION CMN.UFN_AGE
( @DATE_BEG DATETIME,
@DATE_END DATETIME
) RETURNS NVARCHAR(255) AS
BEGIN
DECLARE @Ret NVARCHAR(255) = NULL;
DECLARE @s INT = DATEPART(SECOND, @DATE_END);
DECLARE @n INT = DATEPART(MINUTE, @DATE_END);
DECLARE @h INT = DATEPART(HOUR, @DATE_END);
DECLARE @d INT = DATEPART(DAY, @DATE_END);
DECLARE @m INT = DATEPART(MONTH, @DATE_END);
DECLARE @y INT = DATEPART(YEAR, @DATE_END);
IF (NOT ((@DATE_BEG IS NULL) OR (@DATE_END IS NULL)))
BEGIN
IF (@DATE_BEG < @DATE_END)
BEGIN
IF (@s < DATEPART(SECOND, @DATE_BEG))
BEGIN
SET @s = @s + 60;
SET @DATE_END = DATEADD(MINUTE,-1,@DATE_END);
SET @n = DATEPART(MINUTE, @DATE_END);
SET @h = DATEPART(HOUR, @DATE_END);
SET @d = DATEPART(DAY, @DATE_END);
SET @m = DATEPART(MONTH, @DATE_END);
SET @y = DATEPART(YEAR, @DATE_END);
END
IF (@n < DATEPART(MINUTE, @DATE_BEG))
BEGIN
SET @n = @n + 60;
SET @DATE_END = DATEADD(HOUR,-1,@DATE_END);
SET @h = DATEPART(HOUR, @DATE_END);
SET @d = DATEPART(DAY, @DATE_END);
SET @m = DATEPART(MONTH, @DATE_END);
SET @y = DATEPART(YEAR, @DATE_END);
END
IF (@h < DATEPART(HOUR, @DATE_BEG))
BEGIN
SET @h = @h + 24;
SET @DATE_END = DATEADD(DAY,-1,@DATE_END);
SET @d = DATEPART(DAY, @DATE_END);
SET @m = DATEPART(MONTH, @DATE_END);
SET @y = DATEPART(YEAR, @DATE_END);
END
SET @d = @d + DATEPART(DAY, EOMONTH(@DATE_BEG)) - DATEPART(DAY, @DATE_BEG);
IF (@d = DATEPART(DAY, EOMONTH(@DATE_BEG)))
BEGIN
SET @d = 0
END
ELSE IF (@d > DATEPART(DAY, EOMONTH(@DATE_BEG)))
BEGIN
SET @d = @d - DATEPART(DAY, EOMONTH(@DATE_BEG));
END
ELSE
BEGIN
SET @DATE_END = DATEADD(MONTH,-1,@DATE_END);
SET @m = DATEPART(MONTH, @DATE_END);
SET @y = DATEPART(YEAR, @DATE_END);
END
IF (@m < DATEPART(MONTH, @DATE_BEG))
BEGIN
SET @m = @m + 12;
SET @DATE_END = DATEADD(YEAR,-1,@DATE_END);
SET @y = DATEPART(YEAR, @DATE_END);
END
SET @s = @s - DATEPART(SECOND, @DATE_BEG);
SET @n = @n - DATEPART(MINUTE, @DATE_BEG);
SET @h = @h - DATEPART(HOUR, @DATE_BEG);
SET @m = @m - DATEPART(MONTH, @DATE_BEG);
SET @y = @y - DATEPART(YEAR, @DATE_BEG);
SET @Ret = CONCAT(CASE WHEN (@y < 1) THEN '' ELSE
CONCAT(FORMAT(@y, '00'), ' year(s) ') END,
CASE WHEN (@m < 1) THEN '' ELSE
CONCAT(FORMAT(@m, '00'), ' month(s) ') END,
CASE WHEN (@d < 1) THEN '' ELSE
CONCAT(FORMAT(@d, '00'), ' day(s) ') END,
FORMAT(@h, '00'), ':', FORMAT(@n, '00'), ':', FORMAT(@s, '00'));
END
END
RETURN @Ret;
END
它处理的情况如下:
@dateFrom='2014-04-2413:59:00'@日期='2014-04-2414:01:00' 您的代码为这些值返回了错误的日期。
创建函数CMN.UFN\u AGE
CREATE FUNCTION CMN.UFN_AGE
( @DATE_BEG DATETIME,
@DATE_END DATETIME
) RETURNS NVARCHAR(255) AS
BEGIN
DECLARE @Ret NVARCHAR(255) = NULL;
DECLARE @s INT = DATEPART(SECOND, @DATE_END);
DECLARE @n INT = DATEPART(MINUTE, @DATE_END);
DECLARE @h INT = DATEPART(HOUR, @DATE_END);
DECLARE @d INT = DATEPART(DAY, @DATE_END);
DECLARE @m INT = DATEPART(MONTH, @DATE_END);
DECLARE @y INT = DATEPART(YEAR, @DATE_END);
IF (NOT ((@DATE_BEG IS NULL) OR (@DATE_END IS NULL)))
BEGIN
IF (@DATE_BEG < @DATE_END)
BEGIN
IF (@s < DATEPART(SECOND, @DATE_BEG))
BEGIN
SET @s = @s + 60;
SET @DATE_END = DATEADD(MINUTE,-1,@DATE_END);
SET @n = DATEPART(MINUTE, @DATE_END);
SET @h = DATEPART(HOUR, @DATE_END);
SET @d = DATEPART(DAY, @DATE_END);
SET @m = DATEPART(MONTH, @DATE_END);
SET @y = DATEPART(YEAR, @DATE_END);
END
IF (@n < DATEPART(MINUTE, @DATE_BEG))
BEGIN
SET @n = @n + 60;
SET @DATE_END = DATEADD(HOUR,-1,@DATE_END);
SET @h = DATEPART(HOUR, @DATE_END);
SET @d = DATEPART(DAY, @DATE_END);
SET @m = DATEPART(MONTH, @DATE_END);
SET @y = DATEPART(YEAR, @DATE_END);
END
IF (@h < DATEPART(HOUR, @DATE_BEG))
BEGIN
SET @h = @h + 24;
SET @DATE_END = DATEADD(DAY,-1,@DATE_END);
SET @d = DATEPART(DAY, @DATE_END);
SET @m = DATEPART(MONTH, @DATE_END);
SET @y = DATEPART(YEAR, @DATE_END);
END
SET @d = @d + DATEPART(DAY, EOMONTH(@DATE_BEG)) - DATEPART(DAY, @DATE_BEG);
IF (@d = DATEPART(DAY, EOMONTH(@DATE_BEG)))
BEGIN
SET @d = 0
END
ELSE IF (@d > DATEPART(DAY, EOMONTH(@DATE_BEG)))
BEGIN
SET @d = @d - DATEPART(DAY, EOMONTH(@DATE_BEG));
END
ELSE
BEGIN
SET @DATE_END = DATEADD(MONTH,-1,@DATE_END);
SET @m = DATEPART(MONTH, @DATE_END);
SET @y = DATEPART(YEAR, @DATE_END);
END
IF (@m < DATEPART(MONTH, @DATE_BEG))
BEGIN
SET @m = @m + 12;
SET @DATE_END = DATEADD(YEAR,-1,@DATE_END);
SET @y = DATEPART(YEAR, @DATE_END);
END
SET @s = @s - DATEPART(SECOND, @DATE_BEG);
SET @n = @n - DATEPART(MINUTE, @DATE_BEG);
SET @h = @h - DATEPART(HOUR, @DATE_BEG);
SET @m = @m - DATEPART(MONTH, @DATE_BEG);
SET @y = @y - DATEPART(YEAR, @DATE_BEG);
SET @Ret = CONCAT(CASE WHEN (@y < 1) THEN '' ELSE
CONCAT(FORMAT(@y, '00'), ' year(s) ') END,
CASE WHEN (@m < 1) THEN '' ELSE
CONCAT(FORMAT(@m, '00'), ' month(s) ') END,
CASE WHEN (@d < 1) THEN '' ELSE
CONCAT(FORMAT(@d, '00'), ' day(s) ') END,
FORMAT(@h, '00'), ':', FORMAT(@n, '00'), ':', FORMAT(@s, '00'));
END
END
RETURN @Ret;
END
(@DATE\u BEG DATETIME,
@日期\结束日期时间
)将NVARCHAR(255)返回为
开始
声明@Ret NVARCHAR(255)=空;
声明@s INT=DATEPART(第二个,@DATE\u END);
声明@n INT=DATEPART(分钟,@DATE\u结束);
声明@h INT=DATEPART(小时,@DATE\u结束);
声明@d INT=DATEPART(日期,@DATE\u结束);
声明@m INT=DATEPART(月,@DATE\u结束);
声明@y INT=DATEPART(年份,@DATE\u结束);
如果(不是(@DATE\u BEG为空)或(@DATE\u END为空)))
开始
如果(@DATE\u BEG<@DATE\u END)
开始
如果(@sDATEPART(天,月(@DATE_BEG)),则为ELSE
开始
设置@d=@d-DATEPART(日、月(@DATE_BEG));
结束
其他的
开始
设置@DATE\u END=DATEADD(月-1,@DATE\u END);
设置@m=DATEPART(月,@DATE\u结束);
设置@y=DATEPART(年份,@DATE\u结束);
结束
如果(@m
创建函数CMN.UFN\u
(@DATE\u BEG DATETIME,
@日期\结束日期时间
)将NVARCHAR(255)返回为
开始
声明@Ret NVARCHAR(255)=空;
声明@s INT=DATEPART(第二个,@DATE\u END);
声明@n INT=DATEPART(分钟,@DATE\u结束);
声明@h INT=DATEPART(小时,@DATE\u结束);
声明@d INT=DATEPART(日期,@DATE\u结束);
声明@m INT=DATEPART(月,@DATE\u结束);
声明@y INT=DATEPART(年份,@DATE\u结束);
如果(不是(@DATE\u BEG为空)或(@DATE\u END为空)))
开始
如果(@DATE\u BEG<@DATE\u END)
开始
如果(@s