2014-12-19 164 views
7

我想写一个函数,我可以找到年龄的基础上插入记录而不是getdate()。我想过滤那些注册时间少于18年的用户。 如果我在一年后查询它,它应该仍然基于记录插入日期显示用户为17,而不是当前日期。这是我写的,但它仍然根据当前日期给出的年龄比记录插入日期。任何建议都会非常有帮助。 谢谢函数来计算年龄

--InputDate as DateOfBirth 
--InsertDate as date the record was inserted 

CREATE FUNCTION [dbo].[FindAge] (@InputDate int, @Insertdate datetime) 
RETURNS int 
AS 
BEGIN 
DECLARE @Age as Int 

DECLARE @d DATETIME 
SET @d = CONVERT(DATETIME, CONVERT(VARCHAR(8), @InputDate), 112) 

SELECT @Age=DATEDIFF(year, @d, @Insertdate) 
- CASE WHEN DATEADD(year, DATEDIFF(year, @d, @Insertdate), @d) <= GetDate() 
     THEN 0 ELSE 1 END  

RETURN @Age 
END 

---- Drop Obselete procs 
GO 

更新 其次培根建议,它完美地工作了。

+0

这里你去:http://stackoverflow.com/questions/1572110/how-to-calculate-age-in-years-based-on-date-of-birth-and-getdate – CodeLikeBeaker

+0

快速一瞥后,这看起来像*应该*工作。也许'@ InputDate'参数中有错误的值? –

+0

我的代码已经获得基于getdate的年龄,但我需要基于创建的年龄,我认为我发布的代码应该处理它,但仍然是基于getdate()而不是createdate计算年龄。 – user2908229

回答

5

所有DATEDIFF()确实是从日期组分减去年份。这是非常愚蠢:

select datediff(yy,'2000-12-19','2014-01-01') --14 
select datediff(yy,'2000-12-19','2014-12-18') --14 
select datediff(yy,'2000-12-19','2014-12-19') --14 
select datediff(yy,'2000-12-19','2014-12-20') --14 
select datediff(yy,'2000-12-19','2014-12-31') --14 
select datediff(yy,'2000-12-19','2015-01-01') --15 
select datediff(yy,'2000-12-19','2015-12-31') --15 
select datediff(yy,'2000-12-19','2016-01-01') --16 
select datediff(yy,'2000-12-19','2016-12-31') --16 

不要与去年是365.25天长或类似的东西计算在一年的小时数。这是徒劳的练习,只是保证你会错在每个人的生日附近。

最好的办法是计算一下人类是如何做到的。在美国(以及大多数西方国家,我相信)它是多年来的区别,但是当你通过你的生日,你只算本年度:

declare @birthdate date = '2000-12-19'; 

declare @target date; 

SELECT DATEDIFF(yy, @birthdate, @target) 
     - CASE 
      WHEN (MONTH(@birthdate) > MONTH(@target)) 
       OR (
        MONTH(@birthdate) = MONTH(@target) 
        AND DAY(@birthdate) > DAY(@target) 
       ) 
      THEN 1 
      ELSE 0 
     END 

这里的值,你会得到:

set @target = '2014-01-01' --13 
set @target = '2014-12-18' --13 
set @target = '2014-12-19' --14 
set @target = '2014-12-20' --14 
set @target = '2014-12-31' --14 
set @target = '2015-01-01' --14 
set @target = '2015-12-31' --15 
set @target = '2016-01-01' --15 
set @target = '2016-12-31' --16 

@target更改为getdate()以计算截至目前的年龄。

但是,如果您所在地区使用East Asian age reckoning,则需要使用完全不同的方法来确定某个人的年龄,因为他们在出生当天被视为年龄1,并且他们的年龄每年2月都会增加。

+0

培根位非常感谢。它工作完美。 – user2908229