wlfs
asked on
How to correctly find birthdays in the upcoming 30 days (TSQL)
hi experts
i'm looking for an T-SQL statement which find contacts, who have birthday within the next 30 days.
also take care of date-ranges going over the year-border (for example 20-12-2005 to 19-01-2006) and the 29-02 leap-year effekt.
i have tried quite some time already, but didn't succeed.
thank you for suggestions
cheers woolf
i'm looking for an T-SQL statement which find contacts, who have birthday within the next 30 days.
also take care of date-ranges going over the year-border (for example 20-12-2005 to 19-01-2006) and the 29-02 leap-year effekt.
i have tried quite some time already, but didn't succeed.
thank you for suggestions
cheers woolf
Presumably your contacts table has their date of birth, not the date of their next birthday.
try a function to calculate the days as follows :
create function fnDays2NextBirthday(@birth date datetime, @today datetime)
returns integer
as
begin
declare @birthday datetime
set @birthday = @birthdate
while @birthday < @today set @birthday = dateadd(yy,1,@birthday)
return datediff(dd,@today,@birthd ay)
end
then you can query your contacts by :
select * from contacts where dbo.fnDays2NextBirthday(bi rthdate,ge tdate()) <= 30
try a function to calculate the days as follows :
create function fnDays2NextBirthday(@birth
returns integer
as
begin
declare @birthday datetime
set @birthday = @birthdate
while @birthday < @today set @birthday = dateadd(yy,1,@birthday)
return datediff(dd,@today,@birthd
end
then you can query your contacts by :
select * from contacts where dbo.fnDays2NextBirthday(bi
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
try this .. this should give u all birthdates coming up in the next 30 days starting from today ...
select birthtdate from urtable
where day(birthdate) beween day(getdate()) and day(dateadd(d, 30, getdate()))
and month(birthdate) beween month(getdate()) and month(dateadd(d, 30, getdate()))
select birthtdate from urtable
where day(birthdate) beween day(getdate()) and day(dateadd(d, 30, getdate()))
and month(birthdate) beween month(getdate()) and month(dateadd(d, 30, getdate()))
Rejojohny,
by birthdate 15-06-1972
test since18/05/2005 to 16/06/2005
15 between 18 and 17 --> false
dbeneit.
by birthdate 15-06-1972
test since18/05/2005 to 16/06/2005
15 between 18 and 17 --> false
dbeneit.
ASKER
to BillAn1:
you are right the birthdate lies in the past. I like the function approach and it seems to be a correct solution.
just one question, where exactly would i create the function, within EM (userdefined function ??).
to dbeneit:
although i would prefer one SQL statement, it looks to be quite challenging.
in celkos sql for smarties (SQL92 product independent) the approuch is
SELECT name, dob, CURRENT_DATE
FROM Employees
WHERE INTERVAL (CURRENT_DATE - birthday) YEAR < INTERVAL (CURRENT_DATE - birthday + INTERVAL 45 DAYS) YEAR;
the problem is afaik there is no implementation in MS T-SQL for INTERVAL, which means years of age. DATEDIFF just calculates the difference between the year-numbers of two dates, right?
for your statement although i haven't tested it, i would think you will have a problem with a birthday lets say 02/01/1970 and an observation range starting on 30/12/2005. You convert the birthday to 02/01/2005, right? and therefore it wouldn't show up
to Rejojohny
i think there is a problem.
you are right the birthdate lies in the past. I like the function approach and it seems to be a correct solution.
just one question, where exactly would i create the function, within EM (userdefined function ??).
to dbeneit:
although i would prefer one SQL statement, it looks to be quite challenging.
in celkos sql for smarties (SQL92 product independent) the approuch is
SELECT name, dob, CURRENT_DATE
FROM Employees
WHERE INTERVAL (CURRENT_DATE - birthday) YEAR < INTERVAL (CURRENT_DATE - birthday + INTERVAL 45 DAYS) YEAR;
the problem is afaik there is no implementation in MS T-SQL for INTERVAL, which means years of age. DATEDIFF just calculates the difference between the year-numbers of two dates, right?
for your statement although i haven't tested it, i would think you will have a problem with a birthday lets say 02/01/1970 and an observation range starting on 30/12/2005. You convert the birthday to 02/01/2005, right? and therefore it wouldn't show up
to Rejojohny
i think there is a problem.
wlfs,
DATEDIFF just calculates the difference between the year-numbers of two dates, right? --> yes. the completed years
for your statement although i haven't tested it, i would think you will have a problem with a birthday lets say 02/01/1970 and an observation range starting on 30/12/2005. You convert the birthday to 02/01/2005, right? and therefore it wouldn't show up
-->
It isn't right. The years diference is with end date interval. Then i convet the birthday to 02/01/2006 that it's between 30/12/2005 and 29/01/2006
DATEDIFF just calculates the difference between the year-numbers of two dates, right? --> yes. the completed years
for your statement although i haven't tested it, i would think you will have a problem with a birthday lets say 02/01/1970 and an observation range starting on 30/12/2005. You convert the birthday to 02/01/2005, right? and therefore it wouldn't show up
-->
It isn't right. The years diference is with end date interval. Then i convet the birthday to 02/01/2006 that it's between 30/12/2005 and 29/01/2006
In EM you can create the function as you say in "User Defined Functions". Right-click and select "new user defined function". IN the box that pops up, replace the sample text with the complete text given above, i.e.
create function fnDays2NextBirthday(@birth date datetime, @today datetime)
returns integer
as
begin
declare @birthday datetime
set @birthday = @birthdate
while @birthday < @today set @birthday = dateadd(yy,1,@birthday)
return datediff(dd,@today,@birthd ay)
end
create function fnDays2NextBirthday(@birth
returns integer
as
begin
declare @birthday datetime
set @birthday = @birthdate
while @birthday < @today set @birthday = dateadd(yy,1,@birthday)
return datediff(dd,@today,@birthd
end
Here it is in a simple SQL statement:
select contactinfo
from yourtable
where datediff(Year, birthdate, getdate()) < datediff(Year, birthdate, DateAdd(Day, 30, getdate()));
select contactinfo
from yourtable
where datediff(Year, birthdate, getdate()) < datediff(Year, birthdate, DateAdd(Day, 30, getdate()));
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
yep, same only different :-)
ASKER
to dbeneit: your example with other date range and imagine datebirthday = 1970/12/20
select * from sample where
convert(varchar(10),datead d(year,dat ediff(year ,datebirth day, '2006/01/12'),datebirthday ),120)
between '2005/12/13' and '2006/01/12'
convert(varchar(10), dateadd(year, 36, datebirthday),120) between ...
convert(varchar(10), 2006/12/20, 120) between '2005/12/13' and '2006/01/12' FALSE !!!
nevertheless i liked the idea of converting to varchar.
to jrb1+BillAn1
i think the idea of comparing the age was first mentioned in the Celko approach.
BillAn1 helped me most, although I eventually used the SQL-wording from jrb1.
therefore the points.
to all:
thanks a lot for your valuable input.
it seems MS-TSQL misses the INTEVAL function, which would make things much easier.
select * from sample where
convert(varchar(10),datead
between '2005/12/13' and '2006/01/12'
convert(varchar(10), dateadd(year, 36, datebirthday),120) between ...
convert(varchar(10), 2006/12/20, 120) between '2005/12/13' and '2006/01/12' FALSE !!!
nevertheless i liked the idea of converting to varchar.
to jrb1+BillAn1
i think the idea of comparing the age was first mentioned in the Celko approach.
BillAn1 helped me most, although I eventually used the SQL-wording from jrb1.
therefore the points.
to all:
thanks a lot for your valuable input.
it seems MS-TSQL misses the INTEVAL function, which would make things much easier.
getdate() and DATEADD(month, 1, getdate() )
getdate() (now with a sample)