我有一个表,上面列出了人们的出生日期(目前是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

当前回答

一个只有日期函数的解决方案怎么样,不需要数学,不用担心闰年

CREATE FUNCTION dbo.getAge(@dt datetime) 
RETURNS int
AS
BEGIN
    RETURN 
        DATEDIFF(yy, @dt, getdate())
        - CASE 
            WHEN 
                MONTH(@dt) > MONTH(GETDATE()) OR 
                (MONTH(@dt) = MONTH(GETDATE()) AND DAY(@dt) > DAY(GETDATE())) 
            THEN 1 
            ELSE 0 
        END
END

其他回答

Declare @dob datetime
Declare @today datetime

Set @dob = '05/20/2000'
set @today = getdate()

select  CASE
            WHEN dateadd(year, datediff (year, @dob, @today), @dob) > @today 
            THEN datediff (year, @dob, @today) - 1
            ELSE datediff (year, @dob, @today)
        END as Age

试试这个

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'

这个问题有很多答案,但我认为这一个更接近事实。

我们都知道,datediff(year,…,…)函数只计算日期部分跨越的边界,在本例中是年份。因此,它忽略了一年中的其他时间。

只有当年份从生日开始时,才会给出以完整年份为单位的年龄。它可能不会,但我们可以通过将请求日期调整相同的金额来假装它。

在伪伪代码中,它是这样的:

adjusted_today = today - month(dob) + 1 - day(dob) + 1
age = year(adjusted_today - dob)

+ 1是考虑到月和日数字从1开始,而不是0。 我们把月份和日期分开减去,而不是减去一年中的某一天,是因为二月的长度有令人讨厌的变化趋势。

SQL中的计算是:

datediff(year,dob,dateadd(month,-month(dob)+1,dateadd(day,-day(dob)+1,today)))

dob和today被推定为出生日期和求婚日期。

你可以这样测试:

WITH dates AS (
    SELECT
        cast('2022-03-01' as date) AS today,
        cast('1943-02-25' as date) AS dob
)
select
    datediff(year,dob,dateadd(month,-month(dob)+1,dateadd(day,-day(dob)+1,today))) AS age
from dates;

这是乔治·哈里森的完整年龄。

这比摆弄四分之一日要简洁得多,后者通常会在边缘处给出误导性的值。

如果你有机会创建一个标量函数,你可以使用这样的东西:

DROP FUNCTION IF EXISTS age;
GO
CREATE FUNCTION age(@dob date, @today date) RETURNS INT AS
BEGIN
    SET @today = dateadd(month,-month(@dob)+1,@today);
    SET @today = dateadd(day,-day(@dob)+1,@today);
    RETURN datediff(year,@dob,@today);
END;
GO

请记住,您需要调用dbo.age(),因为Microsoft。

SELECT CAST(DATEDIFF(dy, @DOB, GETDATE()+1)/365.25 AS int)

在尝试了许多方法后,这是100%的工作时间使用现代MS SQL格式函数,而不是转换为风格112。两者都可以,但这是最少的代码。

谁能找到一个日期组合不工作?我不认为有一个:)

--Set parameters, or choose from table.column instead:

DECLARE @DOB    DATE = '2000/02/29' -- If @DOB is a leap day...
       ,@ToDate DATE = '2018/03/01' --...there birthday in this calculation will be 

--0+ part tells SQL to calc the char(8) as numbers:
SELECT [Age] = (0+ FORMAT(@ToDate,'yyyyMMdd') - FORMAT(@DOB,'yyyyMMdd') ) /10000