我有一个表,上面列出了人们的出生日期(目前是nvarchar(25))

我如何将其转换为日期,然后以年为单位计算他们的年龄?

我的数据如下所示

ID    Name   DOB
1     John   1992-01-09 00:00:00
2     Sally  1959-05-20 00:00:00

我希望看到:

ID    Name   AGE  DOB
1     John   17   1992-01-09 00:00:00
2     Sally  50   1959-05-20 00:00:00

当前回答

我得把这个扔出去。如果您使用112样式(yyyymmdd)将日期转换为一个数字,您可以使用这样的计算…

(yyyyMMdd - yyyyMMdd) / 10000 =全年差值

declare @as_of datetime, @bday datetime;
select @as_of = '2009/10/15', @bday = '1980/4/20'

select 
    Convert(Char(8),@as_of,112),
    Convert(Char(8),@bday,112),
    0 + Convert(Char(8),@as_of,112) - Convert(Char(8),@bday,112), 
    (0 + Convert(Char(8),@as_of,112) - Convert(Char(8),@bday,112)) / 10000

输出

20091015    19800420    290595  29

其他回答

试试这个

DECLARE @date datetime, @tmpdate datetime, @years int, @months int, @days int
SELECT @date = '08/16/84'

SELECT @tmpdate = @date

SELECT @years = DATEDIFF(yy, @tmpdate, GETDATE()) - CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END
SELECT @tmpdate = DATEADD(yy, @years, @tmpdate)
SELECT @months = DATEDIFF(m, @tmpdate, GETDATE()) - CASE WHEN DAY(@date) > DAY(GETDATE()) THEN 1 ELSE 0 END
SELECT @tmpdate = DATEADD(m, @months, @tmpdate)
SELECT @days = DATEDIFF(d, @tmpdate, GETDATE())

SELECT Convert(Varchar(Max),@years)+' Years '+ Convert(Varchar(max),@months) + ' Months '+Convert(Varchar(Max), @days)+'days'

因为没有一个简单的答案总是能给出正确的年龄,下面是我想到的。

SELECT DATEDIFF(YY, DateOfBirth, GETDATE()) - 
     CASE WHEN RIGHT(CONVERT(VARCHAR(6), GETDATE(), 12), 4) >= 
               RIGHT(CONVERT(VARCHAR(6), DateOfBirth, 12), 4) 
     THEN 0 ELSE 1 END AS AGE 

这将获得出生日期和当前日期之间的年差。如果出生日期还没过,就减去一年。

任何时候都是准确的——不管闰年或离生日有多近。

最棒的是——没有功能。

我做了很多思考和研究,我有三个解决方案

正确计算年龄 短(大部分) (大部分)是可以理解的。

以下是测试值:

DECLARE @NOW DATETIME = '2013-07-04 23:59:59' 
DECLARE @DOB DATETIME = '1986-07-05' 

解决方案1:我在一个js库中找到了这种方法。这是我的最爱。

DATEDIFF(YY, @DOB, @NOW) - 
  CASE WHEN DATEADD(YY, DATEDIFF(YY, @DOB, @NOW), @DOB) > @NOW THEN 1 ELSE 0 END

它实际上是将年份的差异添加到DOB,如果它比当前日期大,则减去一年。简单的对吧?唯一不同的是,在这里,年龄的差异是相同的。

但是如果你不需要内联使用它,你可以这样写:

DECLARE @AGE INT = DATEDIFF(YY, @DOB, @NOW)
IF DATEADD(YY, @AGE, @DOB) > @NOW
SET @AGE = @AGE - 1

解决方案2:这个我最初是从@bacon-bits复制的。这是最容易理解的,但有点长。

DATEDIFF(YY, @DOB, @NOW) - 
  CASE WHEN MONTH(@DOB) > MONTH(@NOW) 
    OR MONTH(@DOB) = MONTH(@NOW) AND DAY(@DOB) > DAY(@NOW) 
  THEN 1 ELSE 0 END

它基本上是像我们人类一样计算年龄。


解决方案3:我的朋友将其重构为:

DATEDIFF(YY, @DOB, @NOW) - 
  CEILING(0.5 * SIGN((MONTH(@DOB) - MONTH(@NOW)) * 50 + DAY(@DOB) - DAY(@NOW)))

这个是最短的,但也是最难理解的。50只是一个重量,所以只有在月份相同的情况下,日差才重要。SIGN函数是用来将任意值转换为- 1,0或1的。CEILING(0.5 *与Math相同。max(0, value),但是在SQL中没有这样的东西。

select datediff(day,'1991-03-16',getdate()) \\for days,get date refers today date
select datediff(year,'1991-03-16',getdate()) \\for years
select datediff(month,'1991-03-16',getdate()) \\for month

这将正确地处理生日和舍入的问题:

DECLARE @dob  datetime
SET @dob='1992-01-09 00:00:00'

SELECT DATEDIFF(YEAR, '0:0', getdate()-@dob)