you can try this
declare
@DateFrom date = '20140101',
@DateTo date = '20161231'
;with
-- All years between @DateFrom and @DateTo
CTE_Years as (
select datepart(yy, @DateFrom) as y
union all
select y + 1 as y
from CTE_Years
where y < datepart(yy, @DateTo)
),
-- Calculate leap years
CTE_Years2 as (
select
cast(y as nvarchar(4)) as y,
case
when y / 400 * 400 = y then 1
when y / 100 * 100 = y then 0
when y / 4 * 4 = y then 1
else 0
end as Is_Leap_Year
from CTE_Years
),
-- get peoples birth day and month in form 'mmdd'
CTE_People as (
select
FullName,
right(convert(nvarchar(8), dob, 112), 4) as dob
from People
),
-- get peoples birth date in given years
CTE_DOB as (
select
P.FullName,
convert(
date,
Y.y +
case
when Y.Is_Leap_Year = 0 and P.dob = '0229' then '0228'
else P.dob
end,
112
) as dob
from CTE_Years2 as Y
cross join CTE_People as P
)
-- Final query
select *
from CTE_DOB
where dob > @DateFrom and dob < @DateTo
order by DOB asc
TAKE A LOOK AT SQL FIDDLE EXAMPLE
EDIT: Lamak remind me a great way to calculate birthday, so here's edited version
declare
@DateFrom date = '1/1/2014',
@DateTo date = '12/31/2016'
;with
CTE_Years as (
select dateadd(yy, datediff(yy, 0, @DateFrom), 0) as y
union all
select dateadd(yy, 1, y) as y
from CTE_Years
where y < @DateTo
),
CTE_DOB as (
select
P.FullName,
dateadd(yy, datediff(yy, P.dob, Y.y), P.dob) as dob
from CTE_Years as Y
cross join People as P
)
select *
from CTE_DOB
where dob > @DateFrom and dob < @DateTo
order by DOB asc