SQL Server : check if user is old enough - sql

I have to check if a user is old enough. I tried as shown here, but this only works for years.
So, for example 11/7/2003 should be true but 12/12/2003 should be false. But, with my code each of these is true.
Here is my code:
[birthdate]date CHECK(DATEDIFF(year,birthdate,getdate()) >= 18),
How can I write this in another way that the months and days will matter?

Instead of doing arithmetic on the column and checking the result, do arithmetic on GETDATE and do a normal comparison
[birthdate]date CHECK(birthdate <= DATEADD(year, -18, getdate())),
This is good practice in any case for WHERE and JOIN predicates, as it means indexes can be used.

Want to find people who are at least 18, given then date of birth?
SELECT Cast(CURRENT_TIMESTAMP AS date) AS today
, DateAdd(yy, -18, Cast(CURRENT_TIMESTAMP AS date)) AS eighteen_years_ago
;
Anyone born on or before eighteen_years_ago is at least 18 years old.

Check the number of days from date A to B and replace the condition with >= 6570 (365*18).
This method does not check for leap years.

Related

check age based on Date of Birth in SQL Server [duplicate]

This question already has answers here:
How to calculate age (in years) based on Date of Birth and getDate()
(40 answers)
Closed 8 months ago.
I am trying to check the Age of a user from the Date Of Birth to make sure Age is between 16 and 80, When the data is inserted into the table
The Date of Birth is a DATE datatype
I have tired looked for multiple solutions and none of them check it when the data is inserted
I have found this help out article to get the current Date with only the Date: https://learnsql.com/cookbook/how-to-get-the-current-date-without-time-in-t-sql/#:~:text=To%20get%20the%20current%20date%20and%20time%20in%20SQL%20Server,20%2010%3A22%3A34%20.
But i can't seem to get it to work with the CHECK function when creating the table
The other answer does not correctly deal with partial years.
For example, given GETDATE() as 20220626 and a DateOfBirth as 20060627, a calculation based on DATEDIFF will return TRUE. This is because DATEDIFF just counts the number of date boundaries that pass between the two dates.
Another issue is that it cannot use indexes.
A more correct caluclation uses DATEADD against the current date:
WHERE DateOfBirth <= DATEADD(year, -16, CAST(GETDATE() AS date))
AND DateOfBirth > DATEADD(year, -80, CAST(GETDATE() AS date));
You also need CAST AS date otherwise you end up with conversion issues
db<>fiddle
Something like:
DATEDIFF(year, DateOfBirth, GETDATE()) BETWEEN 16 AND 80
Not final code, but could be inserted in your scenario hopefully :)

SQL: Trying to select records 7 days before date

I have a table with a date field called oppo_installdate. This is a date in the future, and I basically want to select records where this date is 7 or fewer days from the current date. I have tried to do this with the query below but it is older returning dates from 2019 as well, and I'm not sure why that's happening.
select * from [CRM_Test].[dbo].[Opportunity]
where (GETDATE() >= DATEADD(day,-7, oppo_installdate))
Could anyone suggest a better way of doing this?
Whenever you're using a WHERE always try to apply any functions to constants, or other functions, never your columns. DATEADD(day,-7, oppo_installdate) will make the query non-SARGable, and could slow it down as any indexes won't be able to be used.
It seems like what you simply want is:
SELECT *
FROM [dbo].[Opportunity]
WHERE oppo_installdate >= DATEADD(DAY, 7, GETDATE());
Note that GETDATE returns a datetime, so if you want from midnight 7 days ago, you would use CONVERT(date,GETDATE()) (or CAST(GETDATE() AS date)).
Use below condition-
select * from [CRM_Test].[dbo].[Opportunity]
where oppo_installdate>= DATEADD(day,-7, GETDATE()) and oppo_installdate<=getdate()
This should give you the records where oppo_installdate is 7 or fewer days away from now:
SELECT *
FROM [dbo].[Opportunity]
WHERE oppo_installdate <= DATEADD(DAY, 7, GETDATE())
and oppo_installdate > getdate();

sql server dateadd() using column name year and not keyword 'year'

I am using DATEADD(year, -3, GETDATE()) to pull the last thee years worth of data on a rolling period.
I also have a column called Year, the view I am creating is using the MyTable.Year and not the sql keyword 'year'.
e.g DATEADD(MyTable.year, -3, GETDATE())
It resolves it every time in the view which is really annoying. I'm a bit rusty, been out of this for about 4 years.
How do I make sure it uses the keyword 'year', I find it strange it is doing this. Any explanation on this would also be helpful. SQL Server 2016
Thanks guys.
EDIT: I have edited my misplaced schema notation and identified the table name, sorry for confusion
I am not sure if I understand correctly, but you want to enforce the keyword, so you want to subtract 3 years from the current date, correct? This should work:
SELECT DATEADD(yy, -3, GETDATE())
or
SELECT DATEADD(yyyy, -3, GETDATE())
(unless you have columns named yy and yyyy ;-))
Otherwise forgive my misunderstanding...
It seems your editor has problems with the keyword YEAR and replaces it with a value from a column that is also called year
This can be solved by using a synonym for the keyword year in the DateAdd function.
So instead of
dateadd(year, -3, getdate())
use
dateadd(yy, -3, getdate())
You could put your table in a subquery and alias [Year] column.
Something like
SELECT ... FROM (SELECT [Year] AS "MyYear" FROM ...) X
(or use CTE)
Then Year would only mean the keyword.

SQL Select Users Who age is 17 between Date Range

Select Users Who were 17 During a range of dates (From and End Date)--
Thanks everyone!
Users
id
birthdate
Example:
User_1 Birthdate 09/28/1996
User_2 Birthdate 08/25/1996
User_3 Birthdate 07/28/1995
User_4 Birthdate 05/25/1995
If Range of dates are FROM 03/05/2013 To End Date 6/05/2013
*User_1 and User_2 Appear because they meet the criteria of being 17 during that time period*
HOWEVER
If Range is From 02/10/2012 and To End Date 06/05/2013
All the Users should appear since they all were 17 at some point during the range of date
I have tried using the Datepart() but i can't clearly think it through to derive at the answer I want
Select u.id, u.birthdate
From Users u
where convert(varchar,DATEPART(MM,u.birthdate))<=DATEPART(MM,'03/05/2013')
With everyone help I came to a conclusion
DATEADD(YY,17,birthdate) between #from and #end
These should do it;
SELECT * FROM users
WHERE birthdate BETWEEN DATEADD(year, -18, '2013-03-05') -- lo date of range
AND DATEADD(year, -17, '2013-06-05'); -- hi date of range
SELECT * FROM users
WHERE birthdate BETWEEN DATEADD(year, -18, '2012-02-10') -- lo date of range
AND DATEADD(year, -17, '2013-06-05'); -- hi date of range
An SQLfiddle to test with.
Note that User_1 turns 17 on 09/28/2013 and User_2 on 08/25/2013, so neither of them is (or should be) included in either range.
My Preferred Method:
Use date datatypes and explicit comparisons between dates. I recommend storing birthdate as a date datatype in SQL Server 2008+, and also using ISO 8601 format for datetime literals to avoid ambiguity.
select id, birthdate
from Users
where birthdate > dateadd(year, -18, '2013-03-05') -- Check lower bounds
and birthdate <= dateadd(year, -17, '2013-06-05'); -- Check upper bounds
Note that I've moved the dateadd function to the constants for this revision. As keenly observed by others, this means less calculation (unless you only had 1 row?), and -- perhaps more importantly -- allows for usage of an index on birthdate.
The BETWEEN Method:
As shown in another answer, using BETWEEN can yield a similar result:
select id, birthdate
from users
where birthdate between dateadd(year, -18, '2013-03-05')
and dateadd(year, -17, '2013-06-05')
However, BETWEEN is inclusive, meaning it will match on all of the range including the end points. In this case, we would get a match on any user's 18th birthday, which is most likely not the desired result (there is often an important difference between ages 17 and 18). I suppose you could use an additional DATEADD to subtract a day, but I like to be consistent in my my usage of BETWEEN as Aaron Bertrand suggests.
What Not To Do:
Do not use DATEPART or DATEDIFF for this type of comparison. They do not represent timespans. DATEDIFF shows the difference in terms of boundaries crossed. See how the following age of just one day would show someone as being a year old already, because the years are technically one apart:
select datediff(year, '2012-12-31', '2013-01-01'); -- Returns 1!
A calculation using 'DATEPART' for years in this fashion would yield the same thing (similarly with months/12, etc., all the way to milliseconds).
Thanks to all who noted the indexing possibility. Let's just not forget the sequence of "Make it work, make it right, make it fast."
Try
SELECT *
FROM
Users
WHERE
DATEDIFF(year,#DATE1, '02/10/2012') = 17
OR
DATEDIFF(year,#DATE2, '06/05/2013') =17
Replacing #DATE1 and #DATE2 above with the required dates.

DATEPART not working like i think it must

select *
from Advertisements
where DepartureDate < DATEPART('dd.mm.yy', '09.10.2010');
but i get
Msg 1023, Level 15, State 1, Line 1
Invalid parameter 1 specified for datepart.
in plsql is this very simple here is so complicated...
Can someone tell me please how can i get all dates that are smaller than today.
You can use this to get the current date:
CONVERT(date, GETDATE())
See the documentation.
Can someone tell me please how can i get all dates that are smaller than today.
SELECT *
FROM Advertisements
WHERE DepartureDate < CONVERT(date, GETDATE())
You seem to be confusing DATEPART with FORMAT_DATE (which does not exist anyway).
DATEPART extracts certain part of a date. Exactly one part.
Dates that are smaller than today are < dbo.CropTime(getdate()), where CropTime is a function which can be written in different ways (such as those described in this question).
Or, in case you are using SQL Server 2008, it's as simple as < cast(getdate() as date).
Would that code really work in PL/SQL? The DATEPART in T-SQL function is used to extract individual portions of a date.
This will get you all the dates before now.
select * from Advertisements where DepartureDate < getdate()
If you're planning to hardcode the date (as your sample code suggests), you just need to format in a way that SQL Server will understand. eg.
select * from Advertisements where DepartureDate < '2010-10-09'
I've been told that date format works on every server regardless of its localization settings. It's certainly worked on every server I've tried it on - but I'm happy to be overruled :-)
What you are looking for I think is
select *
from Advertisements
where DepartureDate < Convert(Date, '09.10.2010', 102)
or possibly
SELECT *
FROM Advertisements
WHERE DepartureDate < Cast(CURRENT_TIMESTAMP as date)
DatePart is used for getting components of the date such as the month, year or day. To get dates that are smaller (older) than now I would do this.
select * from Advertisements where DepartureDate < GetDate();
If I wanted Departure dates that were yesterday or before I could do this.
select * from Advertisements where DepartureDate < Convert(DateTime,Convert(Char(10),GetDate(),121));
or
select * from Advertisements where DepartureDate < Convert(DateTime,floor(convert(int,GetDate())))