sql - T-SQL : calculate age then add character to result

标签 sql sql-server tsql

一直卡在这个上面有一段时间了。假设我有一个 Client 表,如下所示:

Name   BirthDayNum   BirthMonthNum   BirthYearNum
--------------------------------------------------
John       23             12             1965
Jane        4              9             1975
Joe         6              3             1953

目前我正在使用这种语法计算年龄:(抱歉,如果难以阅读)

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。所以,我现在要做的是这个。

继续计算年龄,但我不想返回年或月,而是想以年和月为单位返回年龄,而且还要在值中连接“y”和“m”。前任。上面的 Jane 41y 11m。

所以基本上我想弄清楚如何向返回值添加一个字符,以及如何计算年计算之外的剩余月份。

如有任何帮助,我们将不胜感激!

最佳答案

厌倦了在日期计算上纠缠不清,我创建了一个表值函数来计算以年、月、日、小时、分钟和秒为单位的耗时。

示例

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 将返回

Select A.Name
      ,B.*
 From @YourTable A
 Cross Apply [dbo].[udf-Date-Elapsed](DateFromParts(A.BirthYearNum,A.BirthMonthNum,A.BirthDayNum),GetDate()) B

enter image description here

EDIT - READ ONLY VERSION

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

关于sql - T-SQL : calculate age then add character to result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43126223/

相关文章:

sql - 将行插入同一个表并存储旧/新标识列

sql - 在 Select 查询中使用存储过程

sql - 使用 SQL Server FILESTREAM GUID 作为主键

sql - 从我的 SQL Server 表中删除重复项

sql-server - 触发从 SQL Server 到 Azure 事件中心的事件

c# - 学习如何处理高流量 asp.net mvc 站点的资源?

sql - 查询功能花费的时间太长

sql - 存储过程返回值错误

MySQL 从列中返回几个最大值

sql - 找不到适用于 H2 和 Postgres 的通用 SQL