我找到了几个帮助我解决这个问题的例子,但没有一个可用于数据表。
我在表格中列出了名称和日期,我想根据今天的日,月和年来计算每个人的年龄,例如:
Name DOB Years Months Days
Joe Bloggs 01/10/2012 4 0 11
Steven Wright 29/02/2004 12 7 13
这是我目前使用的查询:
SELECT
Person.Name,
Person.DOB,
DATEDIFF(yy, Person.DOB, GETDATE()) - CASE WHEN (MONTH(Person.DOB) > MONTH(GETDATE())) OR (MONTH(Person.DOB) = MONTH(GETDATE()) AND DAY(Person.DOB) > DAY(GETDATE())) THEN 1 ELSE 0 END AS Years,
DATEDIFF(m, Person.DOB, GETDATE()) - CASE WHEN DAY(Person.DOB) > DAY(GETDATE()) THEN 1 ELSE 0 END AS Months,
DATEDIFF(d, Person.DOB, GETDATE()) AS Days
FROM Person
Where DOB IS NOT NULL
这将从上面的SQL查询中显示Joe Bloggs的以下内容:
Name DOB Years Months Days
Joe Bloggs 01/10/2012 4 48 1472
基本上发生的事情是,这些年份不会从几个月中扣除,等等......所以这是总天数,总月数和总年数,而不是如上所示的分解。
如何使用名为Family
的数据表修改上述查询以使其工作,字段为Name
和DOB
? < / p>
答案 0 :(得分:1)
怎么样
declare @dob date = '22Aug1982'
declare @Yr int = 2016
declare @mon int = 6
declare @dom int = 13
Select @Yr - Year(@dob) - 1 +
case when @mon > Month(@dob) then 1
when @mon < Month(@dob) then 0
else case when @dom >= Day(@dob) then 1
else 0 end end
但我建议你在表中添加一个计算列:
alter table Family
add AgeYears
as Year(getdate()) - Year(dob) - 1 +
case when Month(getdate()) > month(dob) then 1
when month(getdate()) < month(dob) then 0
else case when day(getdate()) >= day(dob) then 1
else 0 end end
如果您还需要额外的月份和旧月,请为这些添加列:
alter table Family
add AgeYears as Year(getdate()) - Year(dob) - 1 +
case when Month(getdate()) > month(dob) then 1
when month(getdate()) < month(dob) then 0
else case when day(getdate()) >= day(dob) then 1
else 0 end end,
AgeMonths as case when Month(getdate()) >= Month(dob)
then Month(getdate()) - month(dob)
else month(dob) - Month(getdate()) end,
AgeDays as case when day(getdate()) >= day(dob)
then day(getdate()) - day(dob)
else day(dob) - day(getdate()) end
答案 1 :(得分:1)
我在TVF看起来有点矫枉过正,但它非常快速准确
Declare @YourTable Table (Name varchar(25),DOB Date)
Insert Into @YourTable values
('Joe Bloggs' ,'2012-10-01'),
('Steven Wright','2004-02-29')
Select A.*
,B.*
From @YourTable A
Cross Apply [dbo].[udf-Date-Elapsed](A.DOB,GetDate()) B
返回
Name DOB Years Months Days Hours Minutes Seconds
Joe Bloggs 2012-10-01 4 0 11 11 3 17
Steven Wright 2004-02-29 12 7 13 11 3 17
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] ('1964-07-29 09:35:00.000',GetDate())
答案 2 :(得分:1)
尝试下面的解决方案,我没有测试过它可能有效:
DECLARE @DOB DATE = '1991-11-19'
SELECT DATEDIFF(M,@DOB,GETDATE())/12 [Year],
DATEDIFF(M,@DOB,GETDATE())%12 [Month],
DATEDIFF(DD,
CASE
WHEN DATEADD(MM,DATEDIFF(MM,@DOB,GETDATE()),@DOB) > GETDATE()
THEN DATEADD(MM,DATEDIFF(MM,@DOB,GETDATE())-1,@DOB)
ELSE DATEADD(MM,DATEDIFF(MM,@DOB,GETDATE()),@DOB)
END,
GETDATE()) [Day]
答案 3 :(得分:1)
我在这个问题上尝试了一些边界条件!如果你愿意,到目前为止似乎还可以。
declare @dob datetime = '19800229'; --date of birth
DECLARE @DAT datetime = '20160301'; --calculation date
SELECT YEAR(@DAT) - YEAR(@dob) -
CASE WHEN MONTH(@DAT) < MONTH(@DOB) OR MONTH(@DAT) = MONTH(@DOB) AND DAY(@DAT) < DAY(@DOB) THEN 1 ELSE 0 END YEARS,
(YEAR(@DAT)*12 - YEAR(@dob)*12 + MONTH(@DAT) - MONTH(@dob) -
CASE WHEN DAY(@DAT) < DAY(@DOB) THEN 1 ELSE 0 END) % 12 MONTHS,
datediff(day,
dateadd(month,(YEAR(@DAT)*12 - YEAR(@dob)*12 + MONTH(@DAT) - MONTH(@dob) -
CASE WHEN DAY(@DAT) < DAY(@DOB) THEN 1 ELSE 0 END) % 12,
dateadd(year, YEAR(@DAT) - YEAR(@dob) -
CASE WHEN MONTH(@DAT) < MONTH(@DOB) OR MONTH(@DAT) = MONTH(@DOB) AND DAY(@DAT) < DAY(@DOB) THEN 1 ELSE 0 END ,@dob)
),@DAT) DAYS