T-SQL:计算年龄然后将字符添加到结果 [英] T-SQL: calculate age then add character to result

查看:34
本文介绍了T-SQL:计算年龄然后将字符添加到结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个问题上停留了一段时间.假设我有一个 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆