T-SQL:计算年龄然后将字符添加到结果 [英] T-SQL: calculate age then add character to result
问题描述
在这个问题上停留了一段时间.假设我有一个 Client
表,就像这里的表:
Been stuck on this one for a while now. Let's say I have a Client
table like the one here:
Name BirthDayNum BirthMonthNum BirthYearNum
--------------------------------------------------
John 23 12 1965
Jane 4 9 1975
Joe 6 3 1953
目前我正在使用以下语法计算年龄:(抱歉,如果难以阅读)
Currently I am calculating the age using this syntax: (sorry if it is hard to read)
DATEDIFF(year, CONVERT(datetime, CAST(client.BirthMonthNum AS varchar(2))
+ '-' + CAST(client.BirthDayNum AS varchar(2))
+ '-' + CAST(client.BirthYearNum AS varchar(4)), 101), GETDATE())
- (CASE WHEN dateadd(YY, DATEDIFF(year, CONVERT(datetime, CAST(client.BirthMonthNum AS varchar(2))
+ '-' + CAST(client.BirthDayNum AS varchar(2))
+ '-' + CAST(client.BirthYearNum AS varchar(4)), 101), GETDATE()),
CONVERT(datetime, CAST(client.BirthMonthNum AS varchar(2))
+ '-' + CAST(client.BirthDayNum AS varchar(2))
+ '-' + CAST(client.BirthYearNum AS varchar(4)), 101)) > getdate() THEN 1 ELSE 0 END) AS 'Client Age'
这将给我以年为单位的年龄.当然,如果我想要几个月,我只需将 DATEDIFF(year
更改为 month
.所以,我现在要做的是这样.
This will give me the age in years. Of course if I want months, I just change the DATEDIFF(year
to month
. So, what I am trying to do now is this.
继续计算年龄,但不是返回年或月,我想以年和月为单位返回年龄,而且还要在值中连接 'y' 和 'm'.前任.上面的 Jane 为 41y 11m.
Continue to calculate the age, but instead of returning either years or months, I would like to return the age in years and months, but also, concat a 'y' and 'm' within the value as well. Ex. 41y 11m for Jane above.
所以基本上我想弄清楚如何向返回值添加一个字符,以及计算超出年份计算的剩余月份.
So basically I am trying to figure out how to add a char to the return value, as well as calculate the remaining months beyond the year calculation.
任何帮助将不胜感激!
推荐答案
厌倦了用日期计算把自己搞得一团糟,我创建了一个表值函数来计算以年、月、日、小时、分钟为单位的经过时间,和秒.
Tired of twisting myself into knots with date calculations, I created a Table-Valued-Function to calculate elapsed time in Years, Months, Days, Hours, Minutes, and Seconds.
示例
Declare @YourTable table (Name varchar(50),BirthDayNum int, BirthMonthNum int, BirthYearNum int)
Insert Into @YourTable values
('John', 23, 12, 1965),
('Jane', 4, 9, 1975),
('Joe', 6, 3, 1953)
Select A.Name
,B.*
,Age = concat(C.Years,'y ',C.Months,'m')
From @YourTable A
Cross Apply (Select DOB = DateFromParts(A.BirthYearNum,A.BirthMonthNum,A.BirthDayNum)) B
Cross Apply [dbo].[udf-Date-Elapsed](B.DOB,GetDate()) C
退货
Name DOB Age
John 1965-12-23 51y 3m
Jane 1975-09-04 41y 6m
Joe 1953-03-06 64y 0m
UDF - 可能看起来有点矫枉过正,但性能非常好
CREATE FUNCTION [dbo].[udf-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
From cteYY,cteMM,cteDD,cteHH,cteMI,cteSS
)
--Max 1000 years
--Select * from [dbo].[udf-Date-Elapsed] ('1991-09-12 21:00:00.000',GetDate())
只是为了说明
没有任何辅助字符串操作的 TVF 将返回
The TVF without any secondary string manipulation would return
Select A.Name
,B.*
From @YourTable A
Cross Apply [dbo].[udf-Date-Elapsed](DateFromParts(A.BirthYearNum,A.BirthMonthNum,A.BirthDayNum),GetDate()) B
编辑 - 只读版本
Select A.Name
,B.*
,Age = concat(DateDiff(MONTH,B.DOB,GetDate())/12,'y ',DateDiff(MONTH,B.DOB,GetDate()) % 12,'m')
From @YourTable A
Cross Apply (Select DOB = DateFromParts(A.BirthYearNum,A.BirthMonthNum,A.BirthDayNum)) B
这篇关于T-SQL:计算年龄然后将字符添加到结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!