Error using the DATEDIFF syntax - sql

I'm trying to find the age of employees from the SAMPLE database using this code:
SELECT
EMPNO,
FIRSTNME,
LASTNAME,
JOB,
BIRTHDATE,
DATEDIFF(HOUR,BIRTHDATE,GETDATE())/8766 AS AGE
FROM EMPLOYEE
WHERE JOB LIKE '%R';
but I keep getting the error :
"HOUR" is not valid in the context where it is used.. SQLCODE=-206,
SQLSTATE=42703
This is using IBM Data Studio 4.1.

Assuming you're using DB2, it doesn't support DATEDIFF or GETDATE(). Instead, just subtract the dates and use CURRENT DATE:
SELECT EMPNO, FIRSTNME, LASTNAME, JOB, BIRTHDATE,
(CURRENT DATE - BIRTHDATE)/365.25 AS AGE
FROM EMPLOYEE
WHERE JOB LIKE '%R'

In DB2, the results of subtracting two dates is a duration in the form `YYYYMMDD'
So for instance, today April 23, 2015 the following:
select current_date - '1972-02-24' as myage
from sysibm.sysdummy1
returns: 430128
Years = 43
Months = 1
Days = 28
So what you want is:
SELECT EMPNO, FIRSTNME, LASTNAME, JOB, BIRTHDATE,
int((CURRENT DATE - BIRTHDATE) / 10000) AS AGE
FROM EMPLOYEE
WHERE JOB LIKE '%R'

Related

Age In Years Of Youngest Employee

I have a table called employees and I I need to get the age of the youngest employee in years.
For example if I look at the table the youngest employee is "57 years old"
The columns:
EmployeeID, Lastname, Title, Birthdate, Hiredate, City, Country
The code I was trying was this:
SELECT MAX(birthdate)
FROM employees;
With that I can get the date of birth of the youngest employee, but now I need to somehow compare it with the current date that would be using "sysdate" and then change it to numbers so that it shows that he is 57 years old, but I have not succeeded
You can use:
SELECT TRUNC(MONTHS_BETWEEN(SYSDATE, MAX(birthdate))/12) AS age
FROM employees;
Which, for the sample data:
CREATE TABLE employees ( id, birthdate ) AS
-- First employee will be 20 tomorrow
SELECT 1, ADD_MONTHS(TRUNC(SYSDATE), -20*12) + INTERVAL '1' DAY FROM DUAL UNION ALL
-- Second employee is 25 today
SELECT 2, ADD_MONTHS(TRUNC(SYSDATE), -25*12) FROM DUAL;
Outputs:
AGE
19
fiddle
You can subtract your MAX(birthdate) from SYSDATE - the result is number of days so you should convert days to years.
WITH
tbl AS
(
select
to_date('09-09-1965', 'dd-mm-yyyy') birthdate,
SYSDATE my_sysdate
from dual
)
SELECT FLOOR((my_sysdate - MAX(birthdate))/ 365) "YEARS_OLD" From tbl
YEARS_OLD
-----------
57
If you don't care much about months and days, a simple option is to extract year from sysdate and youngest birthdate and subtract them:
Sample data:
SQL> with employees (employeeid, lastname, birthdate) as
2 (select 1, 'Little', date '2015-08-25' from dual union all --> youngest
3 select 2, 'Foot' , date '2000-11-13' from dual
4 )
Query:
5 select extract(year from sysdate) - extract(year from max(birthdate)) as age
6 from employees;
AGE
----------
8
SQL>

NOT A VALID MONTH ERROR IN ORACLE FOR BELOW CODE

I am getting 'not a valid month' error for the following code:
SELECT last_name, employee_id, hire_date
FROM employees
WHERE EXTRACT(YEAR FROM TO_DATE(hire_date, 'DD-MON-RR')) > 1998
ORDER BY hire_date;
I don’t see the point for using extract() here. It is suboptimal, because the database needs to apply the function to all values in the column before it is able to filter. I would recommend direct filtering against a literal date:
where hire_date >= date '1999-01-01'
This predicate would take advantage of an index on hire_date. You can even add more columns to the index to entirely cover the query like: (hire_date, last_name, employee_id).
Assuming this is the employees table from Oracle's tutorial, hire_date is already a date column. You don't need to use to_date on it:
SELECT last_name, employee_id, hire_date
FROM employees
WHERE EXTRACT(YEAR FROM hire_date) > 1998
ORDER BY hire_date;

How to show the worked years in SQL with select?

SELECT LAST_NAME
,DEPARTMENT_ID
,ROUND(MONTHS_BETWEEN (SYSDATE, hire_date)) MONTHS_WORKED
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 90
ORDER BY MONTHS_WORKED;
This select is for "hr" schema in Oracle.
The question is how to make it to show the years and months worked?
We could build on your current attempt with months_between. We can divide the result by 12 to get the number of years; the modulo (ie the remainder) represents the number of months:
select
last_name,
department_id,
floor(months_between(sysdate, hire_date)/12) years_worked,
floor(mod(months_between(sysdate, hire_date), 12)) months_worked
from employees
where department_id = 90
order by years_worked, months_worked;

Calculating day difference between 2 date columns where dates are "messy"

Query:
SELECT EmployeeId,
HireDate,
TerminationDate
FROM dbo.Employment
WHERE EmployeeId = 318312
ORDER BY HireDate,
TerminationDate;
Result:
I need to get the number of days this person worked. The problem is that the termination date is "messy" ... meaning, I might not get a termination date for every hire date.
So basically I need to put the dates in "order" ... and then figure out how many days the person had of employment.
In this scenario, it goes as follows:
Person is hired on 2012-12-19, has no termination date and then was re-hired on 2012-12-27.
Person terminates on 2014-03-01 and then is re-hired on 2014-06-05.
Person has no termination date after 2014-06-05 so it is assumed he was re-hired on 2014-06-06 rather than 2014-06-05.
How do I go about creating a query that captures the number of EMPLOYMENT days (excluding gaps), in this scenario?
I would be grouping this by EmployeeID as I'm running this for multiple employees.
This problem is really kicking my butt and I need some help.
This is rather complex but uses LAG to get the previous row, put that in a CTE and then pick out the data with a CASE:
;WITH dataCTE AS
(SELECT EmployeeID,
LAG(HireDate, 1) OVER (ORDER BY HireDate) PreviousHireDate,
LAG(TerminationDate, 1) OVER (ORDER BY HireDate) PreviousTerminationDate,
HireDate, TerminationDate
FROM Employment)
SELECT EmployeeID,
CASE WHEN PreviousTerminationDate IS NULL THEN PreviousHireDate ELSE HireDate END AS HireDate,
TerminationDate,
DATEDIFF(DAY, CASE WHEN PreviousTerminationDate IS NULL THEN PreviousHireDate ELSE HireDate END, TerminationDate) AS NumberOfDays
FROM dataCTE
WHERE TerminationDate IS NOT NULL
Example fiddle here: http://sqlfiddle.com/#!6/1f839e/22

Converting a decimal number to years and months SQL*Plus

I am trying to get an age in years and months from a given DOB. Right now, my code looks like this:
COLUMN name FORMAT A25
SELECT sNo, fName||CHR(13)||lName Name, sex, TRUNC((CURRENT_DATE - dob) / 365.24, 1) Age
FROM Staff
WHERE position IN ('Manager', 'Secretary')
ORDER BY age DESC;
And it gives me Age outputs in decimal numbers (such as 58.6) which I understand, but I am needing to convert that .6 into a month somehow.
I am thinking that my method of doing this conversion isn't the most efficient, but I have been searching for hours for a solution, but to no avail. I've seen DATEDIFF, but I keep getting an invalid identifier error when trying to use it.
Any ideas?
How about something like this:
SELECT sNo, fName||CHR(13)||lName Name, sex,
TRUNC((CURRENT_DATE - dob) / 365.24, 1) Age,
TRUNC(MONTHS_BETWEEN(CURRENT_DATE, dob) / 12) YEARS,
MOD(TRUNC(MONTHS_BETWEEN(CURRENT_DATE, dob)), 12) MONTHS
FROM Staff
WHERE position IN ('Manager', 'Secretary')
ORDER BY age DESC;
And here is the SQL Fiddle.
And this should get you the days as well: http://sqlfiddle.com/#!4/f3a57/4
SELECT sNo, fName||CHR(13)||lName Name, sex,
TRUNC((CURRENT_DATE - dob) / 365.24, 1) Age,
TRUNC (MONTHS_BETWEEN (CURRENT_DATE, dob) / 12) YEARS,
MOD (TRUNC (MONTHS_BETWEEN (CURRENT_DATE, dob)), 12) MONTHS,
TO_DATE (CURRENT_DATE) -
ADD_MONTHS (dob,TRUNC (MONTHS_BETWEEN (CURRENT_DATE, dob))) DAYS
FROM Staff
WHERE position IN ('Manager', 'Secretary')
ORDER BY age DESC;
Good luck.
SELECT sNo, fName||CHR(13)||lName Name, sex,
DATEDIFF(year, dob, Current_Date) - 1 + ' years & ' + dbo.FullMonthSeperation(CURRENT_DATE, dob) + ' months.' AS 'Age'
FROM Staff
WHERE position IN ('Manager', 'Secretary')
ORDER BY age DESC;
I borrowed the function from Calculating number of full months between two dates in SQL as you've got to both consider negative and positive values depending on the time of the year... I'm sure there's a better way to do the months also, the year should be optimal.
Hope this works in SQL Plus! Same concept though.