我有下表
[tblRegistration](
[FirstName] [nvarchar](100) NOT NULL,
[MiddleName] [nvarchar](100) NOT NULL,
[LastName] [nvarchar](100) NOT NULL,
[DateOfBirth] [date] NOT NULL,
[DateOfRegistration] [datetime] NOT NULL,
我的问题是:从表格tblRegistration中选择年龄介于18至25岁之间的所有记录。
谢谢!
答案 0 :(得分:2)
起初我认为DATEDIFF(YEAR, DateOfBirth, GETDATE())
足以获得一年的差异,但SQL Server只计算两个年份数的简单int减法,因此当被问及2016.12.31和2017.01.01之间的差异时它返回1
因此,另外,必须完成几个月和几天的计算:
SELECT *
FROM
(
SELECT
*,
Age = DATEDIFF(yy, DateOfBirth, GETDATE()) -
IIF(DATEPART(m, DateOfBirth) < DATEPART(m, GETDATE()), 0,
IIF(DATEPART(m, DateOfBirth) > DATEPART(m, GETDATE()), 1,
IIF(DATEPART(d, DateOfBirth) > DATEPART(d, GETDATE()), 1, 0)))
FROM tblRegistration
) x
WHERE Age BETWEEN 18 AND 25
答案 1 :(得分:0)
您可以使用以下内容:
SELECT *
FROM tblRegistration
WHERE DATEDIFF(yyyy, DateOfBirth, GetDate()) BETWEEN 18 and 25
答案 2 :(得分:0)
最初我认为问题是this question的重复,但后来我意识到OP不想列出年龄;他希望过滤年龄。这种情况需要采用不同的方法。
要过滤当前年龄,请从当前日期减去年数,并将结果与出生日期进行比较。
DECLARE @today date = CAST(GETDATE() AS date)
DECLARE @from date = DATEADD(day, 1, DATEADD(year, -26, @today))
DECLARE @upto date = DATEADD(day, 1, DATEADD(year, -18, @today))
SELECT *
FROM tblRegistration
WHERE DateOfBirth >= @from AND DateOfBirth < @upto
无需补偿数天和数月。如果列DateOfBirth
恰好是datetime
列,其中包含 time 出生(即它忽略了时间,就像大多数人一样),它甚至可以工作。
是的,它适用于闰年。例如,在2018-02-28上运行查询时,它将:
如果您更喜欢台湾法律(即2月28日正式上午18岁),请调整DECLARE
语句如下。
DECLARE @today date = CAST(GETDATE() AS date)
DECLARE @from date = DATEADD(year, -26, DATEADD(day, 1, @today))
DECLARE @upto date = DATEADD(year, -18, DATEADD(day, 1, @today))
由于DateOfBirth
未包含在函数调用中(与DATEDIFF
方法一样),查询优化器将能够从列{上的索引中完全受益{1}}。
在以下条件下,这可能会带来显着的性能提升:
DateOfBirth
的索引,并且此索引可能会在查询计划中使用(如果还有其他WHERE条件和联接,则可能不是这种情况。)例如,如果您的表中包含100M行,并且您希望检索其中的1%,那么DateOfBirth
方法完成的读取量实际上可能比上面的查询高100倍。这是因为查询优化器无法在DATEDIFF
方法中使用索引搜索;它将回退到索引扫描。