Solved

Getting birthdays within a date range

Posted on 2011-09-20
13
501 Views
Last Modified: 2012-08-14
I had this query:
SELECT psa_nome_abreviado + ' (' + CONVERT(varchar(10), psa_dt_nascimento, 103) + ')(' + CAST(YEAR(GETDATE())-YEAR(psa_dt_nascimento) + 
			CASE WHEN MONTH(psa_dt_nascimento)>MONTH(GETDATE()) OR (MONTH(psa_dt_nascimento)=MONTH(GETDATE()) AND DAY(psa_dt_nascimento)>DAY(GETDATE())) THEN 0 ELSE 1 END AS varchar(2)) + ')' AS 'Nome' 
FROM uv_Inicio 
WHERE cnt_arz_cod_accao NOT IN ('DMS','FCN') 
	AND MONTH(psa_dt_nascimento)=MONTH(GETDATE()) 
	AND cnt_emp_empresa='41'
ORDER BY DATEADD(yy,YEAR(GETDATE())-YEAR(psa_dt_nascimento) + CASE WHEN MONTH(psa_dt_nascimento)<MONTH(GETDATE()) OR (MONTH(psa_dt_nascimento)=MONTH(GETDATE()) AND DAY(psa_dt_nascimento)<DAY(GETDATE())) THEN 1 ELSE 0 END,
	psa_dt_nascimento)

Open in new window

This works fine for getting the birthdays of the current month and not just displaying, but also calculating how many years old said person would be.
Now I need to get this for a range, defined by two variable dates. I also need it to return the age they would be. I've been able to get the results, but not the age, especially for cases when the dates cross years (for example, '31-10-2011' to '29-02-2012'). Also, I'm not sure how to handle ranges that span more than one year. For example, it would be desirable, given a range of '01-01-2010' to '01-01-2015' to see each person for each year, that is, something like:
NameA 01-05-2010 (25)
NameA 01-05-2011 (26)
...
NameA 01-05-2015 (29)
Alternatively, all dates being 01-05-1985 would be fine as well.
If this is too hard, just getting the first instance would be good.
0
Comment
Question by:Cluskitt
  • 6
  • 4
  • 3
13 Comments
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 36567254
>Now I need to get this for a range, defined by two variable dates.

replace:
AND MONTH(psa_dt_nascimento)=MONTH(GETDATE())

by something along these lines:
AND CONVERT(varchar(7), psa_dt_nascimento, 120) >= CONVERT(varchar(7), @start_date, 120)
AND CONVERT(varchar(7), psa_dt_nascimento, 120) <= CONVERT(varchar(7), @end_date, 120)

0
 
LVL 18

Author Comment

by:Cluskitt
ID: 36567318
I can manage the where part. I have adapted the query found here: http://www.berezniker.com/content/pages/sql/microsoft-sql-server/birthday-query-ms-sql-server
I just don't know how to calculate the age, especially for those start in one year and end in another.
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 36567340
what about datediff(month, getdate(), psa_dt_nascimento) / 12 ?
0
 
LVL 18

Author Comment

by:Cluskitt
ID: 36567392
That is based on the current date, not on the range inserted. The range could well be in the future or the past. The age has to be according to the age they would have at that point. I'm just not sure whether I should add from startdate, enddate, or some case check in between.
0
 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 36567404
you can use @start_date or @end_date instead of getdate() ...

what would be the issue is if that is beyond a year range ...
let me see
0
 
LVL 18

Expert Comment

by:lludden
ID: 36567513
I use a function to calculate Age:

CREATE FUNCTION [dbo].[GetAge] (@Birthdate datetime, @Now datetime)  
RETURNS int AS  
BEGIN 
Declare @Age as int
    if @Birthdate is null or @Now is Null 
        set @Age = 0
    ELSE
      BEGIN
		set @Age = datepart(yyyy,@Now) - datepart(yyyy,@Birthdate)
		IF datepart(m,@Now) < datepart(m,@Birthdate) OR ( datepart(m,@Now) = datepart(m,@Birthdate) AND datepart(d,@Now) < datepart(d,@Birthdate) )
			SET @Age = @Age - 1
	  END
Return (@Age)
END

Open in new window


Then in General, your query would be
DECLARE @StartDate datetime = '2010-11-15'
DECLARE @EndDate datetime = '2011-02-12'

SELECT E.Name, E.Birthdate, , dbo.GetAge(e.ActiveBeginDate, CASE WHEN CAST(cast(datepart(yyyy,@StartDate)*10000 + datepart(month,e.ActiveBeginDate)*100 + datepart(d,e.ActiveBeginDate) as char(8)) as datetime) BETWEEN @StartDate AND @EndDate THEN CAST(cast(datepart(yyyy,@StartDate)*10000 + datepart(month,e.ActiveBeginDate)*100 + datepart(d,e.ActiveBeginDate) as char(8)) as datetime) ELSE CAST(cast(datepart(yyyy,@EndDate)*10000 + datepart(month,e.ActiveBeginDate)*100 + datepart(d,e.ActiveBeginDate) as char(8)) as datetime) END) AS Age
FROM MyTable e
WHERE  CAST(cast(datepart(yyyy,@StartDate)*10000 + datepart(month,e.Birthdate)*100 + datepart(d,e.Birthdate) as char(8)) as datetime)
BETWEEN @StartDate AND @EndDate
OR
CAST(cast(datepart(yyyy,@EndDate)*10000 + datepart(month,e.Birthdate)*100 + datepart(d,e.Birthdate) as char(8)) as datetime)
BETWEEN @StartDate AND @EndDate

Open in new window


This handles date ranges over year boundaries.

A cleaner way of doing this would be with a calendar table.

0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 18

Author Comment

by:Cluskitt
ID: 36567539
What do you mean by a calendar table? If it's a better way, then I'm all for it. :)
0
 
LVL 18

Accepted Solution

by:
lludden earned 500 total points
ID: 36567620
Here is a good article on creating a calendar table: http://weblogs.sqlteam.com/dang/archive/2010/07/19/calendar-table-and-datetime-functions.aspx

If you create the table in the link, your query becomes a bit cleaner (still using the getage function)

DECLARE @StartDate datetime = '2010-11-15'
DECLARE @EndDate datetime = '2011-02-12'

SELECT e.Name, e.Birthdate, dbo.GetAge(e.Birthdate,c.CalendarDate) AS Age
FROM Calendar c
INNER JOIN MyTable e ON DATEPART(m,e.Birthdate) = c.CalendarMonth AND datepart(d,e.Birthdate) = c.CalendarDay
WHERE c.CalendarDate BETWEEN @StartDate AND @EndDate

Open in new window


Calendar tables make all sorts of calculations with dates much easier and cleaner.\


0
 
LVL 18

Author Comment

by:Cluskitt
ID: 36572918
Ok, I'm trying to find out exactly what is the ActiveBeginDate field in your first query.
I'm also trying to adapt the calendar table in your link to our country, especially movable holidays. But in the meantime, I would like to get the first one working as well.
0
 
LVL 18

Expert Comment

by:lludden
ID: 36573300
The ActiveBeginDate was from the table I was testing it on.  Replace that with your Birthdate field.
0
 
LVL 18

Author Comment

by:Cluskitt
ID: 36579481
Ok, I almost got it. I just need one thing. How to use the ORDER BY clause with this? I used the calendar suggestion. It's easier and cleaner and it's working fine. But I'm not sure how to order them, especially when the range spans to another year.
0
 
LVL 18

Expert Comment

by:lludden
ID: 36580235
If you are using the calendar table, you can order by the same field you are using in the BETWEEN Clause, c.CalendarDate if you want them to appear in the order they are going to happen (or did happen).
0
 
LVL 18

Author Closing Comment

by:Cluskitt
ID: 36580278
That worked. Everything is great now, and I even got a new Calendar table which I've already used on other queries. Thanks a lot! ;)
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

'Between' is such a common word we rarely think about it but in SQL it has a very specific definition we should be aware of. While most database vendors will have their own unique phrases to describe it (see references at end) the concept in common …
This article describes how to use the timestamp of existing data in a database to allow Tableau to calculate the prior work day instead of relying on case statements or if statements to calculate the days of the week.
Familiarize people with the process of retrieving data from SQL Server using an Access pass-thru query. Microsoft Access is a very powerful client/server development tool. One of the ways that you can retrieve data from a SQL Server is by using a pa…
Via a live example, show how to backup a database, simulate a failure backup the tail of the database transaction log and perform the restore.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now