SQL选择日期范围之间的年龄为17的用户

时间:2013-06-05 18:17:35

标签: sql sql-server-2008

在一系列日期(截止日期和结束日期)中选择17岁的用户 -

谢谢大家!

用户

  • ID
  • 出生日期

示例:

  1. User_1出生日期 09/28/1996

  2. User_2出生日期 08/25/1996

  3. User_3出生日期 07/28/1995

  4. User_4出生日期 05/25/1995

  5. 如果日期范围从03/05/2013 结束日期6/05/2013 * User_1和User_2出现,因为它们符合该时间段内的标准*

    无论其

    如果范围从02/10/2012 结束日期06/05/2013 所有用户都应该出现,因为他们在日期范围内的某个时间点都是17

    我尝试过使用Datepart(),但我无法清楚地想到得出我想要的答案

    Select u.id, u.birthdate
    From Users u
    where convert(varchar,DATEPART(MM,u.birthdate))<=DATEPART(MM,'03/05/2013')
    

    大家帮忙我得出结论

    DATEADD(YY,17,birthdate) between @from and @end
    

3 个答案:

答案 0 :(得分:4)

这些应该这样做;

SELECT * FROM users 
WHERE birthdate BETWEEN DATEADD(year, -18, '2013-03-05')   -- lo date of range
                    AND DATEADD(year, -17, '2013-06-05');  -- hi date of range

SELECT * FROM users 
WHERE birthdate BETWEEN DATEADD(year, -18, '2012-02-10')   -- lo date of range
                    AND DATEADD(year, -17, '2013-06-05');  -- hi date of range

An SQLfiddle to test with

请注意,User_1在2013年9月28日变为17,在2013年8月25日变为User_2,因此它们都不会(或应该)包含在任何一个范围内。

答案 1 :(得分:2)

我的首选方法:

使用日期数据类型和日期之间的显式比较。我建议将birthdate存储为SQL Server 2008+中的日期数据类型,并使用ISO 8601格式存储日期时间文字以避免歧义。

select id, birthdate
from Users
where birthdate > dateadd(year, -18, '2013-03-05') -- Check lower bounds
    and birthdate <= dateadd(year, -17, '2013-06-05'); -- Check upper bounds

请注意,我已将dateadd函数移动到此修订的常量。正如其他人敏锐地观察到的那样,这意味着更少的计算(除非你只有1行?),并且 - 或许更重要的是 - 允许在出生日期使用指数。

BETWEEN方法:

如另一个答案所示,使用BETWEEN可以产生类似的结果:

select id, birthdate
from users 
where birthdate between dateadd(year, -18, '2013-03-05')
        and dateadd(year, -17, '2013-06-05')

但是,BETWEEN具有包容性,这意味着它将匹配所有范围,包括端点。在这种情况下,我们会在任何用户的18岁生日上获得匹配,这很可能不是理想的结果(在17到18岁之间通常会有important difference)。我想您可以使用额外的DATEADD来减去一天,但我希望将BETWEEN用作Aaron Bertrand suggests时保持一致。

什么不该做:

请勿使用DATEPARTDATEDIFF进行此类比较。它们不代表时间跨度。 DATEDIFF显示边界交叉方面的差异。看看只有一天的下一个年龄会如何显示某人已经一岁,因为这些年份在技术上是分开的:

select datediff(year, '2012-12-31', '2013-01-01'); -- Returns 1!

以这种方式使用'DATEPART'多年的计算会产生相同的结果(类似于月/ 12等,一直到毫秒)。

感谢所有注意到索引可能性的人。我们不要忘记"Make it work, make it right, make it fast."

的序列

答案 2 :(得分:-1)

尝试

SELECT * 
FROM
Users
WHERE
        DATEDIFF(year,@DATE1, '02/10/2012') = 17
OR
    DATEDIFF(year,@DATE2, '06/05/2013') =17

将上述@ DATE1和@ DATE2替换为所需日期。