Initially I figured the question was a duplicate of this question, but then I realized OP does not want to list ages; he wants to filter on age. That scenario demands a different approach.
To filter on current age, subtract years from the current date, and compare the result to date of birth.
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
No need to compensate for days and months. It even works if column DateOfBirth
happens to be a datetime
column that includes the time of birth (i.e. it ignores the time, as most people would).
And yes, it works for leap years. For example, when running the query on 2018-02-28, it will:
- exclude persons born on 1992-02-28 (are already celebrating their 26th birthday)
- include persons born on 1992-02-29 (debatable; see https://en.wikipedia.org/wiki/February_29#Born_on_February_29)
- include persons born on 2000-02-28 (celebrating their 18th birthday)
- exclude persons born on 2000-02-29 (again, debatable, but at least consistent with 1992-02-29)
If you prefer Taiwanese legislation (i.e. a 'leapling' formally turns 18 on February 28), then please adjust the DECLARE
statements as follows.
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))
Due to the fact that DateOfBirth
is not wrapped inside a function call (as is the case with the DATEDIFF
approach), the query optimizer will be able to benefit fully from an index on column DateOfBirth
.
This may result in a substantial performance improvement under the following conditions:
- You have an index on
DateOfBirth
, and this index is likely to be used in the query plan (this may not be the case if there are additional WHERE conditions and joins).
- The number of index keys is huge. (For a regular non-filtered index, this number equals the number of records in the table.)
- The number of rows returned is relatively small compared to the number of index keys.
For example, if your table is holding 100M rows, and you expect to retrieve 1% of these, then the amount of reads done by the DATEDIFF
approach may actually be a factor 100 higher than in the query above. This is because the query optimizer cannot use an index seek in the DATEDIFF
approach; it will fall back on an index scan.