我正在尝试编写一个函数,我可以根据插入记录的日期而不是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 :(得分: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岁。重生,每年二月他们的年龄都会增加。