using the datediff function and avg function in the same statement - sql

I am VERY new to any language. In sql, I'm trying to find the avg of data using the datediff function to compute the age. I know the ages, but I simply have no clue as how to write the statement.
when I run this statement, I get the information I'm looking for. However, I also need to use the datediff function to compute the age from the DOB. This is where I get lost. Here is what I have, and I get an error when I run it.
select firstname,lastname, dob
SELECT DATEDIFF(day,'1970-01-01','1978-05-27') AS DiffDate
where occupationId = 164 and gender = 'M';
Again, I new to this and have researched for and answer and to get understanding. I need help.

You've got a few issues with your SQL query.
MySQL DATEDIFF does not have an interval parameter i.e. day. It only takes two datetime parameters. During your research, you must've come across SQL Server documentation.
Use TIMESTAMPDIFF instead (which takes an interval) like so TIMESTAMPDIFF(year, dob, CURDATE()) AS currentage which gets you their current age.
No FROM clause and table is specified, so where are you getting firstname, lastname, dob, occupationId and gender from?
You do not need a sub select query to calculate the age.
The revised query for you (you'll need to specify the table name where you're getting your data from):
SELECT firstname, lastname, dob, TIMESTAMPDIFF(year, dob, CURDATE()) AS currentage
FROM tableName
WHERE occupationId = 164 and gender = 'M';
`

Related

How to use order by with modified column

There is a Table with a age-column. The Value of this column is a varchar because the age of persons under the age of 1 is saved in months with an additional 'm' (9 Month old -> '9m')
I know that this is generally a bad idea and one should rather persist the date of birth, but in this case the age refers to the age on a specific day in history - and additionally this is part of a lesson and the whole point is learning how to treat "weird" data.
My first idea was to put a leading zero on all ages which are not purely numeric:
SELECT *
FROM db
ORDER BY REPLACE(age, (IF ISNUMERIC(age) age ELSE CONCAT('0', age))) DESC;
However this is not a valid SQL-statement and neither are my other attempts.
The question is: How can I adjust the value used for ORDER BY without altering the db?
Another approach would be to select only the rows with a purely numeric age value and a separate select for the remaining rows order both of them separately and combine them afterwards.
My take on this was the following:
(SELECT name, age
FROM titanic
WHERE ISNUMERIC(age)
ORDER BY age DESC)
UNION
(SELECT name, age
FROM titanic
WHERE NOT ISNUMERIC(age)
ORDER BY age);
This is in fact valid or at least it gives me a result. But in the result I can't really see what happened to the order, it looks like the UNION undos everything.
Thanks in advance, will take any tip or even just the name of the function/method I should look into!
Would this work?
SELECT name, age
FROM titanic
ORDER BY isnumeric(age), age
I would use "Case When" structure with some transformations in the "Order by" to get the total number of months for both types of ages.
Select name, age
From tbl
Where age SIMILAR TO '[1-9][0-9]*' Or
age SIMILAR TO '[1-9][0-2]?m'
Order by Case When age SIMILAR TO '[1-9][0-2]?m' Then Substring(age,1,CHAR_LENGTH(age)-1)::int
When age SIMILAR TO '[1-9][0-9]*' Then age::int * 12 End
First off storing age is a poor idea, you must update every row regularly, in this case at least monthly. Storing it as string turns a poor idea into a terrible idea. Not only do you have the maintenance, it is not straight forward nor is it straight forward to insert it. Instead store date-of-birth as a timestamp or date. You can then quickly get age (via the age) you can then use the extract function on the resulting interval at whatever level is desired. If you absolutely must present age with text indicator for either years/months (or even days) you create a view that derives the appropriate value. (see demo)
create or replace view titanic as
select name "Name"
, case when extract( year from age(dob))::integer > 0 then to_char (extract( year from age(dob)), '999') || ' years'
when extract( month from age(dob))::integer> 0 then to_char (extract( month from age(dob)), '99') || ' months'
else to_char (extract( day from age(dob)),'99') || ' days'
end "Age"
from titanic_tbl;

SQL Query on find individuals that age is over 60 as of a specific date

Im new to stack so please go easy on me. Ive looked all over the web and cant find anything that really helps me.
So I need to provide details of all regular academics working in the Computing Department who were
over 60 years old as of 31/12/2014.
my trouble comes with how would I approach showing data of someone 60+ could you minus one date from another date? or is there is possible sql command that I am missing.
my attempt:
SELECT *
FROM staff, department
WHERE DOB <= '31/12/1964'
AND staff.department_ID = department.department _ID
There are functions to calculate the difference between dates, but the most efficient is to first calculate the date that a person would be born to be 60 at 2014-12-31. That way you make a direct comparison to a value, so the database can make use of an index if there is one.
Example for Oracle:
select
PersonId, FirstName, LastName
from
Person
where
Born <= add_months(date '2014-12-31', -60 * 12)
Example for MySQL (eventhough you removed the MySQL tag):
select
PersonId, FirstName, LastName
from
Person
where
Born <= date_sub('2014-12-31' 60 year)
I think In SQL SERVER
Select Datediff(DAYS,'05-19-2015','05-21-2015')
In My SQL
SELECT TIMESTAMPDIFF(HOUR, start_time, end_time)
as difference FROM timeattendance WHERE timeattendance_id = '1484'
The oracle add_months function will help you.
where yourfield < add_months(date '1964-12-31', 60*12 )

I need to find the minimum and average age of students from the birth day

I have a table 'Students' which contains the 'DateOfBirth' of students. I need an SQL statement that I can use in a query to give me the average and minimum ages as fields with those names?I don't want to have to add an age field I just want a SQL statement I can copy and paste that will return me what I need.
SELECT MIN(DateOfBirth) AS Min Age, AVG(DateOfBirth) AS Avg Age FROM Students;
At the moment all the suggestions I have found ask me to specify a value when I run and I have no idea why?
You should first calculate age from date of birth then find average of age
Select AVG(Datediff("yyyy",DateOfBirth,getdate())) as AVGage from Students
Select MIN(Datediff("yyyy",DateOfBirth,getdate())) as MINage from Students
you can also calucate avg,min in one query
Select AVG(Datediff("yyyy",DateOfBirth,getdate())) as AVGage ,
MIN(Datediff("yyyy",DateOfBirth,getdate())) as MINage
from Students
FOR MS ACCESS DB:
Now() provides date and time
Date() provides the date
Time() provides the time
You can Use Date() Function
Select AVG(Datediff("yyyy",DateOfBirth,DATE())) as AVGage ,
MIN(Datediff("yyyy",DateOfBirth,DATE())) as MINage
from Students
Here is SQLFIDDLE FOR SQLSERVER:
SELECT *
FROM Students
GROUP BY DateOfBirth
ORDER BY DateOfBirth DESC
SELECT MIN(DateOfBirth) AS MinAges
FROM Students
SELECT AVG(DateOfBirth) AS AverageAges
FROM Students
Use aggregate functions AVG and MIN.. you can easily google it btw ...To count the age you can use getDate function and count the age - depends on your format of column DateOfBirth ..
select AVG((getDate()-DateOfBirth)/365) as avgAge ,
MIN ((getDate()-DateOfBirth)/365) as minAge
from Students

SQL SUBQUERY in Sqlplus Oracle 11g Help please

Im trying to write a query that will list the Consultant_Id, Name and age for all consultants who have a Grade of 'D' in my Consultant table, and were born more than 30 years ago and have a name that begins with the letter 'L'. I need the output ascending age order. so far i have this but i presume there is multiple errors, any help would be greatly appreciated!
I don't want to seem to be attacking you, but since you said you've been trying to figure this out for a long time and you're stuck, let's look at some of the problems with what you have at the moment.
SELECT Consultant_Id, Name, DOB,
This line has a trailing comma.
FROM Consultant;
This line has a semicolon at the end, terminating the statement, so your where clause is a separate invalid command.
WHERE DOB = (SELECT MAX(DOB <= 01-jan-85) FROM CONSULTANT)
You seem to be using 01-jan-85 as a date, but even if it was in single quotes it would be a string not a date and you should explicitly convert it to a date type; without quotes it would get an invalid identifier (trying to treat 'jan' as a column name). Using the <= comparator inside a max() call isn't valid anyway, and I'm not quite sure what it's supposed to achieve. At best you're getting the most recent DOB from the table in the subquery, and then using that to filter the main query so you will only get the row (or maybe rows) that match that exact date. It won't give you all DOBs more than 30 years ago.
WHERE name( SELECT SUBSTR(Name,1,20) LIKE 'L%' AS ShortName)
name() isn't a function, so perhaps you meant to compare it with =; but as with the DOB check that isn't really what you wan. Your subquery doesn't have a from clause, and isn't correlated with the main query so would return multiple rows, which is an error in itself. As this is the second filter you should be using AND rather than a second WHERE. And the substr() isn't really adding anything since you're using like anyway.
WHERE Grade = 'D'
This is almost OK, but should also be AND not `WHERE.
ORDER BY SUBSTR(DOB, 7,9);
This is doing an implicit conversion of DOB to a string, then getting characters 7 to 15 of whatever your session converts it to by default. Based on the date string you used earlier you means substr(dob, 7, 2), which would give you the 2-digit year in that format; but you're supposed to be ordering by the whole DOB, not just the year.
#HepC has given the actual command you need (aside from the trailing comma on the first line).
I believe this is what you're looking for.
SELECT consultant_id, name, DOB
FROM consultant
WHERE DOB <= ADD_MONTHS((SYSDATE), -360)
AND grade = 'D'
AND name LIKE 'L%'
ORDER BY DOB;
SELECT consultant_id, name, DOB
FROM consultant
WHERE DOB <= ADD_MONTHS(TRUNC(SYSDATE), 12 * -30)
AND name LIKE 'L%'
AND grade = 'D'
ORDER BY DOB;
SELECT Consultant_Id, Name AS ShortName, DOB
FROM Consultant
WHERE DOB < dateadd(year, -30, getdate())
AND name LIKE 'L%'
AND Grade = 'D'
ORDER BY DOB

Create a variable to store a count for DATEDIFF greater than 3

This may be really simple and I'm probably overthinking it. I have to create a variable that stores the number of employees who have been employed with the company for more than 3 years.
Here's what I came up with since the original table does not have the years stored, only a column with the hire date.
DECLARE #YearsEmployed int,
#Plus3 int,
#EmpCount int
SET #YearsEmployed = (SELECT DATEDIFF(YY,HireDate,GetDate())
FROM employees)
SET #Plus3 = #YearsEmployed > 3
SET #EmpCount = COUNT(#Plus3)
SELECT #EmpCount
I've already gotten the "Incorrect syntax near '>'" error and I'm at a loss on how to proceed. Any assistance would be greatly appreciated.
The below query will give you count employees who have been employed with the company for more than 3 years:
DECLARE #EmpCount int
SET #EmpCount = (SELECT count(DATEDIFF(YY,HireDate,GetDate()))
FROM employees where DATEDIFF(YY,HireDate,GetDate()) > 3)
SELECT #EmpCount
COUNT and the condition to pick employees who have worked for more than 3 years can be included within the query and stored in a variable rather using multiple variables and then getting count of those.
Thanks
Seems like a simple query to me:
select count(1)
from employees
where HireDate < dateadd(year, -3, getdate())
Note I have opted for dateadd with the current date, rather than a datediff expression on the column value since the latter is not SARGable.
As far as the code you have written the error comes from trying to assign the result of a boolean expression (#YearsEmployed > 3) to a variable. Furthermore, the query is SET #YearsEmployed = ... will fail if there is more than one row in employees. Additionally, I don't believe COUNT() can be used outside of a query - and even if it can, it's not going to do anything useful.