Get current year's birthday in SQL - sql-server

I have the date of birth (2/3/1967) and I want to convert that to this years birthday.
The select statement would return something like this
userid date_of_birth current_bday
abc123 2/3/1967 2/3/2011
I tried playing around with datepart to get month and day but didn't succeed.
SQL Server 2008 R2

Here's one way to do it:
Use a DATEADD function to add (in years) the difference between the current year and the birth year (to the birth date)
SELECT userid,
date_of_birth,
DATEADD(YY, DATEPART(YYYY, GETDATE()) - DATEPART(YYYY,date_of_birth), date_of_birth) AS current_bday
FROM Users
One thing to worry about is trying to create a date by the individual month and day with the current year. The one problem with that would be trying to create a February 29th birthdate on a year the isn't a leap year. I did test this, and it appears that you will need to specifically account for this, since the DATEADD function gives a date of '2011-02-28' for a birthdate of '2000-02-29'

i think this is more neat:
SELECT userid
,date_of_birth
,DATEADD(YEAR,DATEDIFF(YEAR,date_of_birth,SYSDATETIME()),date_of_birth)
AS current_bday

If you want to grab the "next birthday" from today (not just this year, but possibly next year if the birthday was before today, in this year), you need additional checks.
Here's an example which computes the next birthday for each 29th day of each month in the year 1988 in two ways:
- no check if the bday has come to pass (bday)
- check if bday has come to pass (bday2)
with dobs (dob) as (
select convert(datetime,dob)
from (values
('1988-01-29')
, ('1988-02-29')
, ('1988-03-29')
, ('1988-04-29')
, ('1988-05-29')
, ('1988-06-29')
, ('1988-07-29')
, ('1988-08-29')
, ('1988-09-29')
, ('1988-10-29')
, ('1988-11-29')
, ('1988-12-29')
) as X(dob)
)
select
dob,
dateadd(YY, datepart(YYYY, getdate()) - datepart(YYYY,dob), dob) as bday1
, case when
datepart(month, dateadd(year,datediff(year,dob,getdate()),dob))
<
datepart(month, getdate())
or ( datepart(month, dateadd(year,datediff(year,dob,getdate()),dob))
<
datepart(month, getdate())
and
datepart(day, dateadd(year,datediff(month,dob,getdate()),dob))
<
datepart(day, getdate())
)
then dateadd(year,1+datediff(year,dob,getdate()),dob)
else dateadd(year,datediff(year,dob,getdate()),dob)
end as bday2
from dobs

Related

How to do rolling weeks based on date?

I'm currently at a data analyst student job following an internship and I have do to reports based on the ticketing tool of the company, so, I'm using a pre-calculated table (the administrator have made pre-calculated tables based on his querys).
I have week table with all I need and I have to do a rolling 26 week report.
Because it is calculated that are historized and I don't have creation_date or end_date column.
I can't manage to do this can you help me with this ?
Actually, as a rolling query, if I have 18 weeks for 2021 I will need the 8 weeks last weeks of 2020.
I have this columns : Closed, Week, Month, Backlog... and I need it just for Closed.
I've tried this :
SELECT SUM(CLOSED), WEEK, MONTh, YEAR
FROM E_GROUPE_INTERVENANT_SEMAINE_HISTORY
WHERE MONTH >= Month(getdate())-6
AND YEAR <= YEAR(getdate())
EDIT : The weeks range values 1 trough 53 or 52 it depends on the year, the weeks are weeks of month, I've tried this
SELECT SUM(CLOSED), WEEK, MONTH, YEAR
FROM E_GROUPE_INTERVENANT_SEMAINE_HISTORY
WHERE
YEAR(DATEADD(WEEK, -26, GETDATE())) = YEAR(GETDATE()) - 1
AND
YEAR = YEAR(GETDATE())
AND
MONTH <= Month(DATEADD(WEEK, -26, GETDATE()))
)
group by WEEK, MONTH, YEAR
order by WEEK, YEAR
But I'm only getting week for the current year the previous year doesn't show.
I wonder if it's even possible to have the last year because without the pre-calculated tables I could get the last year with my querys but they want me to use this table.
Thank you for your help.
I don't see what your week value is but this will get you close:
SELECT SUM(CLOSED), WEEK, MONTH, YEAR
FROM E_GROUPE_INTERVENANT_SEMAINE_HISTORY
WHERE (--CURRENT YEAR WHEN YEAR IS NOT CROSSED
YEAR(DATEADD(WEEK, -18, GETDATE())) = YEAR(GETDATE())
AND
YEAR = YEAR(GETDATE())
AND
MONTH >= Month(DATEADD(WEEK, -18, GETDATE()))
)
OR
( --LAST MONTHS OF LAST YEAR WHEN YEAR IS SPANNED
MONTH >= Month(DATEADD(WEEK, -18, GETDATE()))
AND
YEAR = YEAR(DATEADD(WEEK, -18, GETDATE()))
)
OR
(--ALL MONTHS FOR CURRENT YEAR WHEN YEAR IS CROSSED
YEAR(DATEADD(WEEK, -18, GETDATE())) = YEAR(GETDATE()) - 1
AND
YEAR = YEAR(GETDATE())
AND
MONTH <= Month(DATEADD(WEEK, -18, GETDATE()))
)

How to find the past 4 weeks of the same weekday value starting today

I am trying to select records from today and the same day of each week for the last 4 weeks.
Today (Tuesday)
Last Tuesday
The Tuesday before that
The Tuesday before that
I need this to be tied to current date because I am going to run this query every day so I don't want to use a between or something where I manually specify the date range.
Everything I have found or tried so far has pulled the last month of data but not the last 4 weeks of the same weekday.
select *
from table
where thedatecolumn >= DATEADD(mm, -1, GETDATE())
This works but pulls everything from the last month.
If today's date is 7/10/2019 I need
Data from 7/10/2019
Data from 7/3/2019
Data from 6/26/2019
Data from 6/19/2019
Every day I will run this query, so I need it to be dynamic based on the current date.
I believe you want to look back 21 days and then filter those dates that have the same day of week:
select * from table
where thedatecolumn >= DATEADD(DAY, -21, CAST(GETDATE() AS DATE))
and DATEPART(WEEKDAY, thedatecolumn) = DATEPART(WEEKDAY, GETDATE())
You Can try using a recursive cte which starts today and repeatedly substracts 7 days - so you ensure you always land on the same weekday. Following an example:
WITH cteFromToday AS(
SELECT 0 AS WeeksBack, GETDATE() AS MyDate
UNION ALL
SELECT WeeksBack + 1 AS WeeksBack, DATEADD(d, -7, MyDate) AS MyDate
FROM cteFromToday
)
SELECT TOP 5 *
FROM cteFromToday
OPTION ( MaxRecursion 0 );
This is quite simple. Substitute CURRENT_TIMESTAMP here for any given date.
SELECT CONVERT(DATE,CURRENT_TIMESTAMP) AS Today,
DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)) AS LastWeek ,
DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)) AS TwoWeeksAgo,
DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP)) AS ThreeWeeksAgo
SO, if you want to get data for a set of ranges for one entire day with those dates:
SELECT something
WHERE
datetimecolumn >= CONVERT(DATE,CURRENT_TIMESTAMP) AND datetimecolumn < DATEADD(DAY,1, CONVERT(DATE,CURRENT_TIMESTAMP)) -- Todays range,
OR datetimecolumn >= DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1,DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)))-- LastWeek ,
OR datetimecolumn >= DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1,DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)))-- TwoWeeksAgo,
OR datetimecolumn >= DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1, DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP))) -- ThreeWeeksAgo

Display employee anniversary dates within the next month or year of current date

basically trying to create a query that will display employee anniversary dates for upcoming month or year of current date, also would like to display a column that shows the years of service
SELECT
Employee,
Hire_Date
CASE WHEN DATEADD(YY,DATEDIFF(yy,Hire_Date,GETDATE()),Hire_Date)<GETDATE() THEN DATEDIFF(yy,Hire_Date,GETDATE())
ELSE DATEDIFF(yy,Hire_Date,GETDATE())-1 END AS 'Years of service'
FROM
MyTable
looking to display employees with anniversary dates coming up in the coming month or in the next year
Here is the script validated (see pciture below) to display the employees with birth_date coming in the next month
Replace mytable by your own table
declare #mytable as table(employe varchar(100), birth_date datetime,hire_date datetime)
insert into #mytable values
('name1','01/01/1972','01/01/2000') ,
('name2','12/02/1985','01/02/2003') ,
('name3','04/12/1990','03/04/2005') ,
('name4','05/03/1969','12/12/2005') ,
('name5','04/02/1968','12/02/2010') ,
('name6','04/04/1968','12/11/2009') ,
('name7','12/03/1978','01/01/2019') ,
('name8','01/12/2000','03/02/2018') ,
('name9','12/12/1970','05/02/2019') ,
('name10','04/04/1980','04/04/2018')
select employe,birth_date,hire_date,
CASE WHEN DATEADD(YY,DATEDIFF(yy,Hire_Date,GETDATE()),Hire_Date)<GETDATE() THEN DATEDIFF(yy,Hire_Date,GETDATE())
ELSE DATEDIFF(yy,Hire_Date,GETDATE())-1 END AS 'Years of service'
from #mytable where (
month(getdate()) < 12
and
month(birth_date)=1+month(getdate()) )
or (month(getdate())=12 and month(birth_date)=1)
I don't understand well, but, if you need know who make anniversary in the next month, or next year, you should use DATEDIFF function for to filter the data.
Example:
SELECT Employee, Hire_Date, DATEDIFF(year, Hire_Date, getdate()) as YearsService
FROM MyTable
-- if you need fetch to next month, you should use <= 1
WHERE DATEDIFF(month, CONCAT(YEAR(GETDATE()), '-', MONTH(Hire_Date), '-' , DAY(Hire_Date)), GETDATE()) = 1

MSSQL order by previous 7 days

I run this query in MSSQL to get the items, grouping by the last 7 days of the week:
SELECT COUNT(Date_Entered), DATENAME(WEEKDAY, Date_Entered)
FROM my_table
WHERE Board_Name = 'Board'
AND DATEDIFF(DAY,Date_Entered,GETDATE()) <= 7
GROUP BY DATENAME(WEEKDAY, Date_Entered)
In the result, days of the week are sorted in alphabetical order: Friday > Monday > Saturday > Sunday > Thursday > Tuesday > Wednesday
How do I sort by the normal/correct/common sense order, starting with the weekday of 7 days ago and ending with yesterday?
Ordering by MAX(Date_Entered) should work too:
SELECT
COUNT(Date_Entered),
DATENAME(WEEKDAY, Date_Entered)
FROM my_table
WHERE Board_Name = 'Board' AND DATEDIFF(DAY,Date_Entered,GETDATE()) <= 7
GROUP BY DATENAME(WEEKDAY, Date_Entered)
ORDER BY MAX(Date_Entered);
Normally you would want to order by the date ascending, but since you use an aggregate function you would need to group by the date which would ruin it, but since the max(date) in every group is the date you can do max(date) to order.
DATEPART is your friend, try it like this:
SELECT COUNT(Date_Entered), DATENAME(WEEKDAY, Date_Entered),DATEPART(WEEKDAY,Date_Entered)
FROM my_table
WHERE Board_Name = 'Board'
AND DATEDIFF(DAY,Date_Entered,GETDATE()) <= 7
GROUP BY DATEPART(WEEKDAY,Date_Entered),DATENAME(WEEKDAY, Date_Entered)
ORDER BY DATEPART(WEEKDAY,Date_Entered)
If you can't count on data being available for every week then you'd need to do something more based on date calculations. Off the top of my head I think this will be more reliable:
ORDER BY (DATEDIFF(dd, MAX(Date_Entered), CURRENT_TIMESTAMP) + 77777) % 7
EDIT: I wrote that not realizing that the data was already limited to a single week. I thought the intention was to group in buckets by day of week for a longer range of dates.
I'll also comment that to me it is more natural to do the grouping on cast(Date_Entered as date) rather than on a string value and I wouldn't be surprised if it's a more efficient query.

SQL QUERY ( SQL SERVER) Date & Time Difference

I have a SQL SERVER Table which has only one field "StartDate" the records are as follows
**
2011-07-28 19:30:00.000
2011-07-29 21:50:00.000
2011-07-25 09:20:00.000
**
What i want to do is :
SHOW RECORDS if its CURRENT DATE ( todays date ) and the time difference between current time the StartDate is not less then 5 minutes, i have written the following code but it doesnt show me the time difference ?
SELECT * FROM table WHERE DATEDIFF(day, StartDate, GETDATE()) <= 0
SELECT StartDate
FROM table
WHERE YEAR(StartDate)=YEAR(GETDATE())
AND MONTH(StartDate)=MONTH(GETDATE())
AND DAY(StartDate)=DAY(GETDATE())
AND (DATEDIFF(minute, StartDate, GETDATE()) >= 5
OR
DATEDIFF(minute, StartDate, GETDATE()) <= 5)
How about:
SELECT StartDate
,GETDATE()
,DATEDIFF(day, StartDate, GETDATE())
,DATEDIFF(minute, StartDate, GETDATE())
,*
FROM table
WHERE DATEDIFF(day, StartDate, GETDATE()) <= 0
AND DATEDIFF(minute, StartDate, GETDATE()) >= 5
There are two ways to do it one being DateDiff the other is DATEADD. Judging by the way I read your question DateAdd should do it. Here is an example;
SELECT *
FROM [dbo].[TABLE]
WHERE [LAST_UPDATE] > DATEADD(minute,-5,GetDate())
Using BETWEEN is probably a little more optimal than two AND statements (maybe not). Try not to do a calculation on each row if you don't have to. Doing DATEADD only on the current date will only be calculated once.
SELECT
whatever
FROM
table
WHERE
StartDate
BETWEEN FLOOR( CAST( GETDATE() AS FLOAT ) )
AND DATEADD(minute, -5, GETDATE())
I interpret the question as looking for rows where the date is today (between the start of today) but not within the last 5 minutes (and less than 5 minutes ago). That might not be what you were going for.
Hope that helps

Resources