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

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 )

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;

using the datediff function and avg function in the same statement

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';
`

SQL to filter for records more than 30 days old

Suppose I have the following query:
select customer_name, origination_date
where origination_date < '01-DEC-2013';
I would like to select all customers that have an origination date older than 30 days. Is there a way in SQL (oracle, if specifics needed) to specify it in a more dynamic approach than manually entering the date so that I don't need to update the query every time I run it?
Thanks!
Sure try something like this:
select customer_name, origination_date where
origination_date >= DATEADD(day, -30, GETUTCDATE());
This basically says where the origination_date is greater or equal to 30 days from now. This works in Microsoft SQL, not sure but there is probably a similar function on Oracle.
in Oracle, when you subtract dates, by default you get the difference in days, e.g.
select * from my_table where (date_1 - date_2) > 30
should return the records whose date difference is greater than 30 days.
To make your query dynamic, you parameterize it, so instead of using hard coded date values, you use:
select * from my_table where (:date_1 - :date_2) > :threshold
If you are using oracle sql developer to run such a query, it will pop up a window for you to specify the values for your paramteres; the ones preceded with colon.

how to get data whose expired within 45 days..?

HI all,
i have one sql table and field for that table is
id
name
expireydate
Now i want only those record which one is expired within 45 days or 30 days.
how can i do with sql query .?
I have not much more exp with sql .
Thanks in advance,
If you are using mysql then try DATEDIFF.
for 45 days
select * from `table` where DATEDIFF(now(),expireydate)<=45;
for 30 days
select * from `table` where DATEDIFF(now(),expireydate)<=30;
In oracle - will do the trick instead of datediff and SYSDATE instead of now().[not sure]
In sql server DateDiff is quite different you have to provide unit in which difference to be taken out from 2 dates.
DATEDIFF(datepart,startdate,enddate)
to get current date try one of this: CURRENT_TIMESTAMP or GETDATE() or {fn NOW()}
You can use a simple SELECT * FROM yourtable WHERE expireydate < "some formula calculating today+30 or 45 days".
Simple comparison will work there, the tricky part is to write this last bit concerning the date you want to compare to. It'll depend of your environment and how you stored the "expireydate" in the database.
Try Below:-
SELECT * FROM MYTABLE WHERE (expireydate in days) < ((CURRENTDATE in days)+ 45)
Do not execute directly! Depending of your database, way of obtaining a date in days will be different. Go look at your database manual or please precise what is your database.

Selecting products that haven't been made in 2 years

I'm trying to get the products that havn't been made in the last 2 years. I'm not that great with SQL but here's what i've started with and it doesn't work.
Lets say for this example that my schema looks like this
prod_id, date_created, num_units_created.
I'll take any advice i can get.
select id, (select date from table
where date <= sysdate - 740) older,
(select date from table
where date >= sysdate - 740) newer
from table
where newer - older
I'm not being clear enough.
Basically i want all products that havn't been produced in the last 2 years. Whenever a product is produced, a line gets added. So if i just did sysdate <= 740, it would only give me all the products that were produced from the beginning up til 2 years ago.
I want all products that have been produced in the at least once, but not in the last 2 years.
I hope that clears it up.
GROUP BY with HAVING
select id, max(date)
from table
group by id
having max(date) < add_months(sysdate,-24)
I'd use SQL's dateadd function.
where date < dateadd(year,-2,getdate())
would be a where clause that would select records with date less than 2 years from the current date.
Hope that helps.
EDIT: If you want to go by days, use dateadd(d,-740,getdate())
Maybe something like this?
select id, date
from table
where date <= (sysdate - 730);
SELECT id FROM table WHERE date + (365*2) <= sysdate;
Use SELECT id, date, other, columns ... if you need to get them at the same time.