I tested it in SQL Server, because it has the DATEADD
, GETDATE
functions.
Your query returns wrong results when the range of +-30 days goes across the 1st of January, i.e. when the range belongs to two years.
Your calculation
DATEADD(Year, DATEPART(Year, GETDATE()) - DATEPART( Year, T0.[BirthDate]), T0.[BirthDate])
moves the year of the BirthDate
into the same year as GETDATE
, so if GETDATE
returns 2016-01-01
, then a BirthDate=1957-12-25
becomes 2016-12-25
. But your range is from 2015-12-01
to 2016-01-30
and adjusted BirthDate
doesn't fall into it.
There are many ways to take this boundary of the year into account.
One possible variant is to make not one range from 2015-12-01
to 2016-01-30
, but three - for the next and previous years as well:
from `2014-12-01` to `2015-01-30`
from `2015-12-01` to `2016-01-30`
from `2016-12-01` to `2017-01-30`
One more note - it is better to compare original BirthDate
with the result of some calculations, rather than transform BirthDate
and compare result of the function. In the first case optimizer can use index on BirthDate
, in the second case it can't.
Here is a full example that I tested in SQL Server 2008.
DECLARE @T TABLE (BirthDate date);
INSERT INTO @T (BirthDate) VALUES
('2016-12-25'),
('2016-01-25'),
('2016-02-25'),
('2016-11-25'),
('2015-12-25'),
('2015-01-25'),
('2015-02-25'),
('2015-11-25'),
('2014-12-25'),
('2014-01-25'),
('2014-02-25'),
('2014-11-25');
--DECLARE @CurrDate date = '2016-01-01';
DECLARE @CurrDate date = '2015-12-31';
DECLARE @VarDays int = 30;
I used a variable @CurrDate
instead of GETDATE
to check how it works in different cases.
DATEDIFF(year, @CurrDate, BirthDate)
is the difference in years between @CurrDate
and BirthDate
DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate)
is @CurrDate
moved into the same year as BirthDate
The final DATEADD(day, -@VarDays, ...)
and DATEADD(day, +@VarDays, ...)
make the range of +-@VarDays
.
This range is created three times for the "main" and previous and next years.
SELECT
BirthDate
FROM @T
WHERE
(
BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate))
AND
BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate), @CurrDate))
)
OR
(
BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)+1, @CurrDate))
AND
BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)+1, @CurrDate))
)
OR
(
BirthDate >= DATEADD(day, -@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)-1, @CurrDate))
AND
BirthDate <= DATEADD(day, +@VarDays, DATEADD(year, DATEDIFF(year, @CurrDate, BirthDate)-1, @CurrDate))
)
;
Result
+------------+
| BirthDate |
+------------+
| 2016-12-25 |
| 2016-01-25 |
| 2015-12-25 |
| 2015-01-25 |
| 2014-12-25 |
| 2014-01-25 |
+------------+