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

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 :)

Related

Find rows that have yesterdays date -- Invalid column? [duplicate]

This question already has answers here:
How to use alias column name in where clause in SQL Server
(5 answers)
Using new columns in the "where" clause
(5 answers)
Closed 20 days ago.
Goal: I am trying to get the rows in a table that have yesterdays date (but the original column is in datetime).
What I've tried:
I was able to figure out how to get yesterdays date from https://learnsql.com/cookbook/how-to-get-yesterdays-date-in-t-sql/
But I also had to cast the DateTime from the table to date to match that yesterdays date was in Date format. So the SO articles like SQL statement to select all rows from previous day did not work.
When I try to find the matching rows from my DB Table, it says:
Invalid column name 'YesterdayDate'
SQL:
SELECT cast(DateEnded as date) AS YesterdayDate
FROM [dbo].[V]
WHERE YesterdayDate = DATEADD(DAY, -1, CAST(GETDATE() AS date));
How can I correctly do this?
In fact don't do it that way. You want to avoid calling functions on columns in your WHERE clause as they can make the query unsargable i.e. unable to use indexes. Instead use the actual column, and rather than converting to a date use a datetime window of the previous day.
SELECT CAST(DateEnded AS date) AS YesterdayDate
FROM [dbo].[V]
WHERE DateEnded >= DATEADD(DAY, -1, CAST(GETDATE() AS date))
AND DateEnded < CAST(GETDATE() AS date);

SQL Server : check if user is old enough

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.

SQL Server : select count of Todays Transactions

I was wondering if someone could help me as I can't seem to find an answer to the following that I have been searching for.
Select
Count(pm1.number) As number
From
SCenter.probsummarym1 As pm1
Where
pm1.open_time >= Today()
I have the above that works great if I put in the date as '01-05-2015'
But I want today's date each day when it refreshes.
Sorry if this is pretty basic but I am just lost on this one
GETDATE() will return the current date and time.
You may then use a CAST() or CONVERT() to strip the time value and be left with just the date, ie.
SELECT CONVERT(VARCHAR(10), GETDATE(), 110)
The above code would return 05-19-2015 for today.
Select
Count(pm1.number) As number
From SCenter.probsummarym1 As pm1
Where
pm1.open_time >= GETDATE() //or CONVERT(VARCHAR(10), GETDATE(), 110)

query to select data from this day [duplicate]

This question already has answers here:
In SQL Server, what is the best way to filter items for an entire day
(3 answers)
Closed 8 years ago.
I have a database table that has Datelogged columns from type Datetime (Sql server 2008 r2)
The Datelogged value is like this 2014-10-22 12:57:36.583
I want to do a query to select all the rows that its date is today (I care about year, month, and day) but not (hour, second.)
This is my query
string query = "SELECT * FROM Orders WHERE PrintTime is NULL WHERE Datelogged = #Datelogged";
but I didn't know what should I do to tell the query to compare just on year-month-day
Based on #Aaron Bertrand comment
It appears that it is better to use a Date Range from current day midnight (00:00:00) to < tomorrow at midnight.
Query copied from his comment.
DateLogged >= CONVERT(DATE, #DateLogged) AND
DateLogged < DATEADD(DAY, 1, CONVERT(DATE, #DateLogged))
Also see: Bad habits to kick : mis-handling date / range queries By Aaron Bertrand
(Old Answer)
You can use CONVERT(DATE, Datelogged) to get Date part without time.
"SELECT * FROM Orders WHERE PrintTime is NULL AND CONVERT(DATE, Datelogged) = #Datelogged"
Make sure you pass the parameter value using Date property in C# like:
cmd.Paramaters.AddWithValue("#Datelogged", DateTime.Today);// or DateTime.Now.Date
Also make sure to remove multiple WHERE from your query and use AND or OR to combine two conditions depending on your requirement.
Get the minimum date time range for current date and maximum date time range for today. Then, compare it with the logged date value.
Conversion operator on any table column adds extra conversion overhead and leads to inefficient use of index. Should be avoided when possible.
SELECT * FROM Orders
WHERE PrintTime is NULL
AND (Datelogged > dateadd(DD, -1, cast( GETDATE() as date)) AND Datelogged < dateadd(DD, 1, cast( GETDATE() as date)));

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.