How to find most recent birthday - sql

Table1
ID Dateofbirth
001 01/01/1988 'dd/mm/yyyy
002 01/05/2001
....
From the table1, i want to find the most recent birthday of each id. Most recent birthday should validate with system date.
Expected output
ID Dateofbirth MostRecentBirthday
001 01/01/1988 01/01/2012
002 01/05/2001 01/05/2011
....
ouput explanation
For 001, most recent birthday is 01/01/2012
For 002, most recent birthday is 01/05/2011 ' because still we are not reached this date 01/05/2012

Similar to the answer to the previous question:
select ID,
Dateofbirth,
dateadd(yy,
datediff(yy,Dateofbirth,getdate()) -
case when dateadd(yy,datediff(yy,Dateofbirth,getdate()),Dateofbirth)>getdate()
then 1 else 0 end,
Dateofbirth) MostRecentBirthday
from ...

Assuming column type is DATE (or DATETIME):
SELECT id,
Dateofbirth,
CONVERT(date,
DATEPART(month, Dateofbirth) + '/'
+ DATEPART(day, Dateofbirth) + '/'
+ CASE WHEN DATEPART(month, Dateofbirth) < DATEPART(month, GETDATE()) OR
(DATEPART(month, Dateofbirth) = DATEPART(month, GETDATE()) AND DATEPART(day, Dateofbirth) < DATEPART(day, GETDATE()))
THEN DATEPART(year, GETDATE())
ELSE DATEPART(year, GETDATE())-1
END,
101) AS MostRecentBirthday
FROM your_table
Not tested, but should be pretty close.

If you use an Age UDF, then the query can simply be:
SELECT
ID,
Dateofbirth,
DATEADD(year, dbo.Age(Dateofbirth), Dateofbirth) AS MostRecentBirthday
FROM
...

This idea may help
SELECT
ID,
dateofbirth,
convert(nvarchar(10), day(dateofbirth)) + "/" +
convert(nvarchar(10), month(dateofbirth)) +
CASE month(getdate()) > Month(dateofbirth)
WHEN TRUE THEN convert(nvarchar(10), year(getdate()))
ELSE CASE month(getdate()) < Month(dateofbirth)
WHEN TRUE THEN convert(nvarchar(10), Year(getdate())-1)
ELSE CASE day(getdate()) >= day(dateofbirth)
WHEN TRUE THEN Year(getdate())
ELSE Year(getdate())-1)
END
END
END MostRecentBirthday
FROM .....

Related

How to extract data from 1st day of the month till today's date -1

I am trying to extract all the data that has the datetime from 1st day of the month till yesterday, for example:
01/06/2017 - 22/06/2017
I have used this code:
Select *
from testDb.dbo.Company1
WHERE MONTH(CreatedDate) = MONTH(dateadd(dd, -1, GetDate())) AND
YEAR(CreatedDate) = YEAR(dateadd(dd, -1, GetDate()))
EDIT
My column for CreatedDate, its data type is DateTime. Not sure if there is any difference tho.
But this prints out all the data from 01/06/2017 - 23/06/2017. What code should I write such that it will print all data till (today's date-1)? Thanks for the help and have a great day!
Instead of comparing the month and year components separately, try bounding your result set using a range of two complete data points, one being the start of the month, and the other being yesterday.
SELECT *
FROM testDb.dbo.Company1
WHERE
CreatedDate BETWEEN DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0) AND
DATEADD(day, -1, CAST(GETDATE() AS date))
Demo
Try this query --
SELECT *
FROM testDb.dbo.Company1
WHERE DATEPART(Month, CreatedDate) = Datepart(Month, GETDATE())
AND DATEPART(Day, CreatedDate) <= DATEPART(Day, Getdate())
Edit:
SELECT *
FROM testDb.dbo.Company1
WHERE DATEPART(Month, CreatedDate) = Datepart(Month, GETDATE())
AND DATEPART(Day, CreatedDate) < DATEPART(Day, Getdate())
Edit 2:
SELECT CONVERT(VARCHAR(30),CreatedDate,120) As [CreatedDate]
FROM testDb.dbo.Company1
WHERE DATEPART(Month, CreatedDate) = Datepart(Month, GETDATE())
AND DATEPART(Day, CreatedDate) < DATEPART(Day, Getdate())
This though wont work when today is the first day of the month
SELECT *
FROM your_table
WHERE createdDate BETWEEN
CAST('1 ' + DateName(month, GetDate()) + ' ' +Year(GetDate()) as datetime)
AND DATEADD(day, -1, GETDATE() )
I think this where clause does what you want:
where createdDate >= dateadd(month, 0, datediff(month, 0, getdate())) and
createdDate < cast(getdate() as date)

Pulling a month of rows in SQL Server based on a dynamic day

I have a table in SQL server that looks like this (there are other fields, but there are the only 2 I care about):
-----------------------------------------
| DraftDay (int)| MonthlyFee (money)|
-----------------------------------------
1 18.75
2 15.25
2 15.25
3 15.25
3 28.12
4 15.25
4 3.75
4 18.19
5 12.75
6 13.80
6 14.25
... ...
... ...
What I am trying to do is write a query that will group by DraftDay and sum the MonthlyFee field. Simple enough. But the hard part is, I need to get the date of one month ago, plus one day and pull the days from that day to the current day. For example, if today is 4/3/2014, then I need to pull all days between 3/4/2014 and 4/3/2014. My result set should look like this:
3/4/2014 37.19
3/5/2014 12.75
3/6/2014 28.05
... ...
... ...
4/1/2014 18.75
4/2/2014 30.50
4/3/2014 43.37
I have created this query:
SELECT
CAST(CAST(DATEPART(MONTH, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(2)) + '/' +
CAST(CASE WHEN EftDraftDay>28 THEN 28 ELSE EftDraftDay END AS VARCHAR(2)) + '/' +
CAST(DATEPART(YEAR, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(4)) AS DATETIME) AS DraftDate,
SUM(MonthlyPayment) AS MonthlyPayment FROM dbo.Advertiser
WHERE IsDeleted=0
AND IsPaidInFull=0
AND IsAdvertiserActive=1
AND EftDraftDay>0
AND (CAST(CAST(DATEPART(MONTH, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(2)) + '/' +
CAST(CASE WHEN EftDraftDay>28 THEN 28 ELSE EftDraftDay END AS VARCHAR(2)) + '/' +
CAST(DATEPART(YEAR, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(4)) AS DATETIME)) >=
CAST(CAST(DATEPART(MONTH, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(2)) + '/' +
CAST(DATEPART(DAY, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(2)) + '/' +
CAST(DATEPART(YEAR, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(4)) AS DATETIME)
GROUP BY
CAST(CAST(DATEPART(MONTH, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(2)) + '/' +
CAST(CASE WHEN EftDraftDay>28 THEN 28 ELSE EftDraftDay END AS VARCHAR(2)) + '/' +
CAST(DATEPART(YEAR, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(4)) AS DATETIME)
Because today's date is 4/17/2014, I should be getting results back from 3/18/2014 thru 4/17/2014. The results I'm getting back are only from 3/18/2014 thru 3/28/2014. How can I also add 4/1/2014 thru 4/17/2014 into my result set? I thought about a UNION, but those don't seem to work well with GROUP BY's.
After trying to figure this out and looking at my query, I think I am totally over engineering this. My query looks so complex for such a simple thing. Can anyone please help me out with this?
Try this:
declare #lastmonth date = convert(date,dateadd(day,1,dateadd(month,-1,getdate())))
declare #thismonth date = convert(date,getdate())
select
case
when draftday < datepart(day,#thismonth)
then convert(date, cast(datepart(yyyy,#thismonth) as varchar) + right('00'+cast(datepart(MM,#thismonth) as varchar),2) + right('00'+cast(cast(draftday as varchar) as varchar),2))
else convert(date, cast(datepart(yyyy,#lastmonth) as varchar) + right('00'+cast(datepart(MM,#lastmonth) as varchar),2) + right('00'+cast(cast(draftday as varchar) as varchar),2))
end,
sum(monthlyfee) from tbl
group by draftday
This will treat days before current day as belonging to current month, and others as from last month, and then sum up. Please let me know if this is doing what you expect.
I'd use the Calendar table (http://www.dbdelta.com/calendar-table-and-datetime-functions/), something like this:
declare #d datetime ='20140403'
select c.CalendarDate, sum(#t.MonthlyFee)
from calendar c
left join #t on c.CalendarDay = #t.DraftDay
where CalendarDate between dateadd(month, -1, #d)+1 and #d
group by c.CalendarDate

GET Persons Birthday, Days Left Until Bday, and Persons Age this year in MS SQL 2012

The script I have below works great for displaying birthdays but it will not display the birthday on the birthday date and also how do I get the day's left for that person's birthday ? and finally how old will the person be on this birthday.
THE SCRIPT IS:
SELECT *
FROM DRIVERS e
WHERE 1 = CASE WHEN MONTH(GETDATE()) < MONTH(DATEADD(WK,
DATEDIFF(WK, 0, GETDATE())+1,-1))
THEN CASE WHEN MONTH(DOB) = MONTH(GETDATE()) + 1
AND DAY(DOB) >= 1
AND DAY(DOB) < DAY(DATEADD(WK,
DATEDIFF(WK, 0, GETDATE())
+ 1, -1)) THEN 1
WHEN MONTH(DOB) = MONTH(GETDATE())
AND DAY(DOB) >= DAY(GETDATE())
AND DAY(DOB) <= DAY(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))) THEN 1
ELSE 0 END
ELSE CASE WHEN MONTH(DOB) = MONTH(GETDATE())
AND DAY(DOB) >= DAY(GETDATE())+1
AND DAY(DOB) < DAY(DATEADD(WK,
DATEDIFF(WK, 0, GETDATE())
+ 1, -1)) THEN 1
ELSE 0
END
END
--// So I need the following:
--// 1. Show birthday on birthday date.
--// 2. Show Days Left until Birthday.
--// 3. Show Age of Person on upcoming birthday.
Thanks so much for any help with this.
Try this for age:
CASE
WHEN DATEPART(DAYOFYEAR, DOB) < DATEPART(DAYOFYEAR, GETDATE())
THEN DATEDIFF(YEAR, DOB, GETDATE())
ELSE
DATEDIFF(YEAR, DOB, GETDATE())-1
END
and this for days until birthday:
DATEDIFF(DAY, GETDATE(), DATEADD(YEAR,DATEDIFF(YEAR, DOB, GETDATE()), DOB))
It might need some tweaking, but showed correct results when I did some basic tests.
SELECT
FLOOR(DATEDIFF(DAY, GETDATE(), DATEADD(YEAR,DATEDIFF(YEAR, DOB, GETDATE()), DOB))) AS BDAYin
, FLOOR(DATEDIFF(dd,DOB, GETDATE()+7) / 365.25) AS AGEwillTurn
FROM DRIVERS
WHERE 1 = (FLOOR(DATEDIFF(dd,DOB,GETDATE()+7) / 365.25))-(FLOOR(DATEDIFF(dd,DOB,GETDATE()) / 365.25))

Filter out rows that have a computed column value of null

I have an SQL query something along the lines of:
SELECT CONVERT(varchar, DATEPART(month, titlStreaming)) + '/' + CONVERT(varchar, DATEPART(day, titlStreaming)) + '/' + CONVERT(varchar, DATEPART(year, titlStreaming)) AS [Day],
COUNT(titlTitleID) AS Total
FROM Title
GROUP BY DATEPART(year, titlStreaming), DATEPART(month, titlStreaming), DATEPART(day, titlStreaming)
ORDER BY DATEPART(year, titlStreaming) DESC, DATEPART(month, titlStreaming) DESC, DATEPART(day, titlStreaming) DESC
That generally returns a table like:
Day | Total
--------------------
4/23/2013 | 2
...
NULL | 14234
What I would like to do is filter out the row that has a NULL value from returning.
Because Day is a computed column obviously I cannot simply do a WHERE Day IS NOT NULL.
I'll admit my knowledge of SQL is quiet lacking so any help or suggestions would be appreciated.
as far as all dateparts depend on titlStreaming a where condition on titlStreaming should be enough.
....
From Title
where titlStreaming is not null
Group by ....
You can use a subquery:
select *
from (SELECT CONVERT(varchar, DATEPART(month, titlStreaming)) + '/' + CONVERT(varchar, DATEPART(day, titlStreaming)) + '/' + CONVERT(varchar, DATEPART(year, titlStreaming)) AS [Day],
COUNT(titlTitleID) AS Total
FROM Title
GROUP BY DATEPART(year, titlStreaming), DATEPART(month, titlStreaming), DATEPART(day, titlStreaming)
) t
where [day] is not null
ORDER BY [day] DESC

Case Statement with Datediff and DatePart

Can some one help with a case statement please, what I need is the query to show is the following. I know there are ways to do this easier but I just need help on the Case Statement.
--If the Current Month is ‘Less Than’ the DOB Month, then take ‘1’ of the Total Years to give me 41.
--If the Current Month is ‘Greater Than’ the DOB Month then the Age is Correct.
--However if the Current Month is ‘Equal’ to the DOB Month then we need to go to Day level to get the correct Age.
Set #DOB = '01 November 1971'
Set #Today = GETDATE()
SELECT Datediff(Year,#DOB,#Today) AS Years,
Datepart(Month,#DOB) As DOB_Month,
Datepart(Day, #DOB) as DOB_Day,
DatePart(Month, #Today) As Current_Month,
Datepart(Day,#Today) AS Current_Day
Try this :
DECLARE #DOB DATE= '01 November 1971'
DECLARE #TODAY DATE = GETDATE()
SELECT CASE
WHEN DATEPART(MONTH, #TODAY) < DATEPART(MONTH,#DOB) THEN DATEDIFF(YEAR,#DOB,#TODAY) - 1
WHEN DATEPART(MONTH, #TODAY) > DATEPART(MONTH,#DOB) THEN DATEDIFF(YEAR,#DOB,#TODAY)
ELSE
CASE
WHEN DATEPART(DAY, #TODAY) < DATEPART(DAY,#DOB) THEN DATEDIFF(YEAR,#DOB,#TODAY) - 1
ELSE DATEDIFF(YEAR,#DOB,#TODAY)
END
END
You can try this :
case
when DatePart(Month, #Today) > Datepart(Month,#DOB) then Datediff(Year,#DOB,#Today)
when DatePart(Month, #Today) < Datepart(Month,#DOB) then (Datediff(Year,#DOB,#Today) - 1)
when DatePart(Month, #Today) = Datepart(Month,#DOB) then
case
when DatePart(Day, #Today) >= Datepart(Day,#DOB) then (Datediff(Year,#DOB,#Today) )
when DatePart(Day, #Today) < Datepart(Day,#DOB) then (Datediff(Year,#DOB,#Today) - 1 )
end
end as AgeCompleted,
declare #DOB date = '19680411'
select datediff(year, #DOB, getdate())- case when month(#DOB)*32 + day(#DOB) >
month(getdate()) * 32 + day(getdate()) then 1 else 0 end