sql where clause issue with date older than 5 years - sql

How do I not include people with a birth date older than 5 years from today's date? Here is what I have, I just dont know how to put it in my where clause.
SELECT firstname, lastname, age, gender, birthdate
FROM Person
WHERE ... ... ...

I would use:
dateadd(year,-5, getdate()) >= birthdate

datediff(year,yourdate,getdate()) > 5

The best way to do this is:
where birthdate <= dateadd(year, -5, getdate())
The reason this is "best" is because all the operations are on non-columns values (getdate() rather than birthdate). This allows the engine to take advantage of an index on birthdate when processing this where clause.

Use DATEADD to subtract 5 years from todays date:
SELECT firstname, lastname, age, gender, birthdate
FROM Person
WHERE birthdate < DATEADD(year, -5, GETDATE())

Related

Comparing dates in Transact-SQL

Why does comparison works weird in this example?
Dates, which are birthdays, are:
1990-03-22
1998-03-20
1990-03-22
2002-12-02
2004-03-18
2004-03-20
2004-03-25
I'm doing this
WHERE DATEADD(YY, 18, jun.birth_date) >= DATEADD(YY, 1, GETDATE())
Which, I think, should cut off all the entries of people older than 18 in a year from today. But it does absolutely opposite, here's what I get:
2004-03-18
2004-03-20
2004-03-25
And I get right results when I seacrh for entries less and even than date in the next year.
Why does it work like this?
This is what your have...
WHERE
someone's date of birth + 18 years
>=
Today's date + 1 year
In English, thats; where the 18th birthday is a year or more in the future.
I think what you really want (if you want people who are 18 or older) is... WHERE the birthdate is earlier than today's date minus 18 years (18 or more years ago)
WHERE
Jun.birth_date <= DATEADD(YY, -18, GETDATE())
If you want people who are 18, or older today, then take 18 years off today, don't add years to the DoB column, as that makes the query non-SARGable:
SELECT birth_date
FROM dbo.YourTable
WHERE birth_date <= DATEADD(YEAR, -18, CONVERT(date,GETDATE()));
Why don't you use datediff, instead of dateadd?
with d as (
select cast('1990-03-22' as date) as birthDate union all
select cast('1998-03-20' as date) as birthDate union all
select cast('1990-03-22' as date) as birthDate union all
select cast('2002-12-02' as date) as birthDate union all
select cast('2004-03-18' as date) as birthDate union all
select cast('2004-03-20' as date) as birthDate union all
select cast('2004-03-25' as date) as birthDate
)
select *
from d
where datediff(year,birthDate, getdate()) >= 18
It's easier to understand the behaviour.

Construct a date using a column's value to compare against a range (T-SQL)

I am trying to query our employee table to return all the employees who are celebrating a hiring-date anniversary within the next week. Here's the query:
SELECT firstname, lastname, hiredate
FROM employees
WHERE hiredate IS NOT NULL
AND DateFromParts(Year(getdate()),Month(hiredate),Day(hiredate)) BETWEEN getDate() AND DateAdd(day,7,getDate())
The hiredate column is a datetime column with the month, day, and year they were hired. I thought using DateFromParts would let me construct their anniversary date for this year so I could compare that to the date range. But it's throwing the error:
Cannot construct data type date, some of the arguments have values
which are not valid.
Am I on the right track and just missed something, or is there a better way?
This is caused by someone having a HireDate of Feb 29 during a Leap Year, and since this year is not a Leap Year, it is failing to construct the valid date.
Try using the following to construct the date based on the number of days since the beginning of the year:
SELECT firstname, lastname, hiredate
FROM employees
WHERE hiredate IS NOT NULL
AND Case When Month(hiredate) = 2 And Day(hiredate) = 29 Then
DateAdd(Day, DatePart(DayOfYear, hiredate) - 1, DateFromParts(Year(getdate()), 1, 1))
Else DateFromParts(Year(getdate()), Month(hiredate), Day(hiredate))
End BETWEEN getDate() AND DateAdd(day,7,getDate())
The easiest way to find if someone had his birthday within a given period uses following approach:
calculate the age the day before the start of the period: age1
calculate the age at the end of the period (you will need that anyway to know the exact age): age2
now check if the age changed; WHERE age1 <> age2
Calculating an age in SQL Server is horrible, but as this is a common task you might have a UDF already, otherwise:
DATEDIFF (YEAR, birthdate,
GETDATE())
- CASE WHEN 100 * MONTH(GETDATE()) + DAY(GETDATE())
< 100 * MONTH(birthdate) + DAY(birthdate)
THEN 1
ELSE 0
END AS age
Now adjust it using DateAdd(day,-1,getDate()) and DateAdd(day,7,getDate())

Select statement that gives the names,ages, and counrty of birth when female but needs to give DateOfBirth as an age instead of DOB

So far I have:
Select FullName, DateOfBirth, CountryOfBirth
FROM Students
WHERE Gender = F
however I want the DateOfBirth to be Displayed as an age under an age heading.
Can I use this: (Datediff("yyyy",DateOfBirth,DATE())) if so where in my original statement would it go?
Select FullName, DATEDIFF(year,DateOfBirth,DATE()) , CountryOfBirth FROM Students WHERE Gender = F
You can modify the DATEDIFF function to calculate the age according to the date instead of just the year
You probably don't want to use datediff with yyyy as that won't actually give you the ages correctly. It'll give you the years since the year they were born. If someone has a birthday later in the year than today then they'll be returned as a year older than they are.
What I would do is use datediff with hour or day:
datediff(day, DateOfBirth, DATE()) / 365
or
datediff(hour, DateOfBirth, DATE()) / (24 * 365)
You need a proper method for calculating age - an example is shown here:
https://stackoverflow.com/a/29127001/3527297
Yes, you can use the DateDiff function to achieve this. That function would replace the DateOfBirth column in the query, to become:
SELECT FullName, DATEDIFF(yyyy, DateOfBirth, DATE()) As Age, CountryOfBirth
FROM Students
WHERE Gender = F
Unfortunately, there is some contention around leap years in SQL. There isn't a straightforward way to deal with them. There's an updated statement below, but it awkwardly uses cases:
DECLARE #startDate DATETIME = '1984-01-02'
DECLARE #endDate DATETIME = '2015-01-01'
Select Case
When DatePart ( day, #startDate) <= DatePart (day , #endDate )
Then DateDiff ( year, #startDate, #endDate)
When DateDiff (year , #startDate , DateAdd (year , - 1, #endDate)) = - 1
Then 0
Else DateDiff (year , #startDate , DateAdd (year , - 1, #endDate))
End As DoB
You may want to consider putting this DateOfBirth check into a Function for brevity/re-usability.

select month and year from Date of birth IN sql

i have table with DOB column ('2012-05-29 00:00:00.000') and few other fields , i need to select the data for DOB between 6 months to 6 Years. I tried using the below SQL but this is not giving me the right data. any help will be appreciated.
select * from dbo.xyz
where ( FLOOR(DATEDIFF(MONTH, birth_date , GETDATE()) % 12) >=6
AND FLOOR(DATEDIFF(DAY, birth_date , GETDATE()) / 365.25) <= 6
)
When using dates, the advice is to use functions only on the non-column values. In other words, modify getdate(), not birth_date:
select *
from dbo.xyz
where birth_date between dateadd(year, -6, getdate()) and dateadd(month, -6, getdate())
This has two advantages. First, it makes the where clause "sargable", which means an index can be used on the comparison. More importantly, the alternative of using datediff() doesn't quite work as expected. datediff() counts the number of calendar boundaries between two values. So, 2014-12-31 and 2015-01-01 are one day apart, one month apart, and even one year apart.
Try this
select * from dbo.xyz
where DATEDIFF(MONTH, birth_date , GETDATE()) between 6 and 72
Here is another option that will allow indexing on birthdate.
select *
from dbo.xyz
where birthdate > DATEADD(YEAR, -6, GETDATE())
and birthdate < DATEADD(MONTH, -6, GETDATE())

Get the correct days in vacation accumulation report

I need acculate how many days between today and Employee hiredate(but do not care the year). That mearn if one employee hire in 07/1/2012, i want to get a result is today 07/15/2013-07/1/2013, that is 15 days. I do not need the hire year 2012.
i play around with the dateadd and datediff but just did not get the correct result.
SELECT
Co Employee,
LastName,
FirstName,
dateadd(dd, DATEDIFF(dd,CURRENT_TIMESTAMP,0),HireDate)
FROM dbo.PREH
You could use modulus division:
SELECT DATEDIFF(DAY,'20120101',GETDATE())%365
The downside is that you're treating leap year the same as every other year, which you could handle with case logic.
In your code:
SELECT
Co Employee,
LastName,
FirstName,
DATEDIFF(DAY,HireDate,GETDATE())%365 AS DaysThisYear
FROM dbo.PREH
This is a bit brute force, perhaps, but it seems to work. The idea is to add a number of years to the hiredate, then to check that against the current date. When it is greater, use one fewer years:
select (case when DATEADD(year, datediff(year, hiredate, getdate()), hiredate) < GETDATE()
then DATEDIFF(dd, DATEADD(year, datediff(year, hiredate, getdate()), hiredate), getdate())
else DATEDIFF(dd, DATEADD(year, datediff(year, hiredate, getdate()) - 1, hiredate), getdate())
end)
from preh;
The problem is that datediff() with year returns the number of times that the year boundary is crossed, not the number of years between two dates as a span. So, there is one year between 2012-12-30 and 2013-01-01, and there is one year between 2012-01-01 and 2013-12-31.
It sounds like you're dropping the year just as part of formatting the output. Formatting shouldn't affect the underlying data though. The last element of your tuple should be:
datediff(day, HireDate, getdate())
That way you can do arithmetic on the data, and save the formatting for downstream, when it's needed.