当日期、月份和年份在sql server的不同列中时计算年龄

当日期、月份和年份在sql server的不同列中时计算年龄,sql,database,sql-server-2008,Sql,Database,Sql Server 2008,我有一个数据库,其中出生日期存储在三个不同的列中,因为nvarchar第一列是日期,第二列是月份,第三列是年份现在如何使用这些列计算年龄 -谢谢你试试这个 create function dbo.dob ( @dob datetime ) returns datetime as begin declare @out datetime select @out = dateadd(yy,datediff(yy,convert(date,@dob),getdate())-1,@dob) return

我有一个数据库,其中出生日期存储在三个不同的列中,因为nvarchar第一列是日期,第二列是月份,第三列是年份现在如何使用这些列计算年龄 -谢谢你试试这个

create function dbo.dob
(
@dob datetime
)
returns datetime
as
begin
declare @out datetime
select @out = dateadd(yy,datediff(yy,convert(date,@dob),getdate())-1,@dob)
return @out
end
仅在几年内:

select  convert(varchar,case    when mm > month(getdate()) 
                then datediff(yy,convert(date,yy+mm+dd),getdate())-1 
                when mm = month(getdate()) and dd>day(getdate()) 
                then datediff(yy,convert(date,yy+mm+dd),getdate())-1 
                else datediff(yy,convert(date,yy+mm+dd),getdate())end)+' Years '
 from table   
对于整个dob,包括天数:

select  convert(varchar,case    when mm > month(getdate()) then datediff(yy,convert(date,yy+mm+dd),getdate())-1 
                when mm = month(getdate()) and dd>day(getdate()) then datediff(yy,convert(date,yy+mm+dd),getdate())-1 
                else datediff(yy,convert(date,yy+mm+dd),getdate())end)+' Years '+
        convert(varchar,case    when month(getdate()) = mm and dd>day(getdate())  then datediff(mm,dbo.dob(convert(date,yy+mm+dd)),getdate())-1%12 
                else datediff(mm,dbo.dob(convert(date,yy+mm+dd)),getdate())%12 end)+' Months And '+
        convert(varchar,datediff(dd,dbo.dob(yy+mm+dd),getdate())%case when year(getdate())%4 = 0 and mm > 2 then 366 else 365 end)+' Days '
from table

这应该能帮你解决问题:

declare @t table (DOBYear nvarchar(19), DOBMonth nvarchar(7),
                  DOBDay nvarchar(13))
insert into @t(DOBYear,DOBMonth,DOBDay) values ('1978','05','17')

select (DATEPART(year,CURRENT_TIMESTAMP) - DOBYear)
    - CASE
        WHEN DATEPART(month,CURRENT_TIMESTAMP) < DOBMonth THEN 1
        WHEN DATEPART(month,CURRENT_TIMESTAMP) = DOBMonth AND
             DATEPART(day,CURRENT_TIMESTAMP) < DOBDay THEN 1
        ELSE 0 END
from @t
基本上,你只需要减去年份值,然后在一些情况下,它会超过1,所以如果必要的话,我们会调整这个值

我们还依赖于这样一个事实:DATEPART函数返回int,然后数据类型优先规则将强制nvarchar值在进行比较之前也转换为int。如果要使转换显式化,可以使用CONVERTint对每个列引用进行包装。

查询: 输出:
如果此人出生在实际月份的前一个月,或本月的前一天或等于今天,则年龄是从出生年份到当前年份的年数。如果不是,则相同,减去1

CREATE TABLE BirthDates
(YEAR INT,
MONTH INT,
DAY INT)
2014年9月18日今天的测试数据:

INSERT INTO BirthDates VALUES(2013,9,19) -- 0 the frist birthday is still to come
INSERT INTO BirthDates VALUES(2013,9,18) -- 1 today is the first birthday
INSERT INTO BirthDates VALUES(2013,9,17) -- 1 the first birthday was yesterday
INSERT INTO BirthDates VALUES(2013,8,31) -- 1 the first birthday was last month
INSERT INTO BirthDates VALUES(2013,10,1) -- 0 the first birthday will be next month
必选查询

SELECT B.*,
    CASE WHEN (MONTH(GETDATE()) > B.MONTH 
               OR (MONTH(GETDATE()) = B.MONTH AND DAY(GETDATE()) >= B.DAY))
        THEN YEAR(GETDATE()) - B.YEAR 
        ELSE YEAR(GETDATE()) - B.YEAR - 1 END AS AGE
FROM BirthDates B

OP更新了他们的问题。他们实际上想要的是年龄,而不是出生日期。OP已经更新了他们的问题。他们实际上想要的是年龄,而不是出生日期。那么月和日呢?当我被问及我的年龄时,我说我40岁,我不是说我40岁,3个月,12天,7小时,35分钟。你这么说吗?可能是
SELECT B.*,
    CASE WHEN (MONTH(GETDATE()) > B.MONTH 
               OR (MONTH(GETDATE()) = B.MONTH AND DAY(GETDATE()) >= B.DAY))
        THEN YEAR(GETDATE()) - B.YEAR 
        ELSE YEAR(GETDATE()) - B.YEAR - 1 END AS AGE
FROM BirthDates B