My exercise says create a query to get a list of employees hired in the period from July 1998 to December 1999. The list must contain the employee id, the last and first name and the monthly salary – given that the table contains the yearly salary and that employees get 12 salaries per year using the hr table schema.
What I've written is:
select employee_id, last_name, first_name, salary/12 as monthly_salary
from employees
where hire_date between ... and ... ;
My issue is: How should I search the hire_date with only the month and year as mentioned above eg. July 1998?
If all you have is the year and month number and are looking for the first and last dates of that month, you can find that easily with the to_date and last_date functions.
SQL> select to_date('2013/03', 'YYYY/MM') first from dual;
FIRST
---------
01-MAR-13
SQL> select last_day(to_date('2013/03', 'YYYY/MM')) last from dual;
LAST
---------
31-MAR-13
Use these functions to build your boundary dates in your query.
Note: you could also do something with trunc(hire_date, 'MM'), but that would probably prevent the optimizer from using an index on hire_date, which is not desirable.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
In my Oracle database I have a table employees with thousand of records.
It has columns:
employee_id
first_name
last_name
email
salary
hire_date
I want to show employees who joined in each year with a hire_date on the 23th day of month March.
However, when using below SELECT statement it shows only empty records.
SELECT FIRST_NAME,LAST_NAME,EMAIL
FROM EMPLOYEES
WHERE to_char(hire_date, 'mon')='dec'
AND to_char(hire_date, 'DD')='23';
tryng to display a records but it is no showing.what should be aproper format for displaing date and month of particular records.
ANSI/ISO SQL solution is EXTRACT():
SELECT FIRST_NAME, LAST_NAME, EMAIL
FROM EMPLOYEES
WHERE extract(day from hire_date) = 23
AND extract(month from hire_date) = 3
First of all, in your question you say you are looking for employees on the 23rd of March, but in the where clause of your example query, you are searching for employees hired on the 23rd of December.
To prevent any differentiating spellings of months in different languages and compare using one filter in your where clause instead of two, you can use a query like this one.
SELECT FIRST_NAME, LAST_NAME, EMAIL
FROM EMPLOYEES
WHERE TO_CHAR (hire_date, 'MMDD') = '0323';
Oracle's to_char function is applied correctly using the column hire_date of type DATE as argument with formats models DD for day-of-month.
By the way, this function with most of the format-literals (at least DD and MON) is also supported by PostgreSQL and MySQL.
Possible Issues: with the abbreviated month-name
I wonder if mon for month abbreviated name works correctly.
At least the right-hand side of month is an issue because lowercase dec instead uppercase DEC. Also pay attention to the locale used to format month-names. In English locales DEC for December should work.
For the month of March as stated in your question, you would use 'MAR' as right-hand side of the month-comparison (not DEC).
Simplification
Simpler is to use combined format like TO_CHAR(hire_date, 'DD-MON') = '23-DEC' respectively using the month-abbreviation in your database-locale.
Test using group-by with count
SELECT TO_CHAR(hire_date, 'DD-MON') as hired_day, COUNT(*)
FROM employees
GROUP BY TO_CHAR(hire_date, 'DD-MON')
WHERE TO_CHAR(hire_date, 'DD') = '23'
Should return the day and month (formatted in your locale) with a count of hired employees - restricted to the 23th for all months recorded (max 12 rows in result-set).
You can also omit the last line with WHERE condition to get all days, resulting in a longer list.
I have a table of 30,000 names and birthdays. I need to pull the current month's birthdays out. Date format is 06/01/2020. Appreciate any help I can get.
Table name is BIRTHDAYS. I need to pull out all these 3 fields data for that person.
First Name Last Name Birth Date
Steve Johnson 06/24/1985
Joe Smith 06/05/2000
Brenda Cater 04/20/1970
Cathy Proctor 01/10/1972
Try this:
SELECT NAME,BIRTHDAY
FROM schema_name.table_name
WHERE to_char(BIRTHDAY,'mm') = to_char(sysdate, 'mm')
Assuming the column is named Birth Date of type DATE in table birthdays:
select to_char("Birth Date",'MM') from birthdays;
to_char will work, but here is another option:
select first_name, last_name, birth_date
from birthdays
where EXTRACT(MONTH from TO_DATE(birth_date,'MM/dd/YYYY')) = EXTRACT(MONTH from sysdate)
Query
List the emps who joined in the year 1992
Employees Table
EmployeeID LastName Title BirthDate HireDate
1 Davolio Sales Representative 1948-12-08 00:00:00.000 1992-05-01 00:00:00.000
2 Fuller Vice President, Sales 1952-02-19 00:00:00.000 1993-08-14 00:00:00.000
3 Leverling Sales Representative 1963-08-30 00:00:00.000 1992-04-01 00:00:00.000
Query Code
Select * from employees
where HireDate like '1992%'
Result
I am getting null result. How to get result where year starts with 1992
Same way to find out employees hired in May - 1992
Select * from employees where HireDate like '1992-05%'
Results in null and no columns
While converting to a varchar appears a straightforward solution, its performance will not be optimal, because its not sargable - indexes can't be used once you start transforming columns i.e. by converting them, when used in a where clause.
Using a window compare removes the need for a function and performs better as follows:
-- Find all employees hired in 2020
SELECT *
FROM dbo.Employees
WHERE Hiredate >= '01 Jan 2020' and HireDate < '01 Jan 2021'
-- Find all employees hired in May 2020
SELECT *
FROM dbo.Employees
WHERE Hiredate >= '01 May 2020' and HireDate < '01 Jun 2020'
You simply need to change the dateformat of the data that you are querying to give you only the year.
We can do this by using DATEPART(YY)
like this
DATEPART(YY,hiredate)
Also, you will need to replace LIKE for an exact matching system by using =
WHERE DATEPART(YY,hiredate) = ('1992')
Therefore your end script should be;
SELECT
*
FROM employees
WHERE DATEPART(YY,hiredate) = ('1992')
LIKE is a string function. But your column is presumably a date/time value of some sort. It is much better to use comparisons -- using standard date/time formats. For your question:
where HireDate >= '1992-01-01' and HireDate < '1993-01-01'
or:
where HireDate >= '19920101' and HireDate < '19930101'
The hyphen form uses ISO standard date formats that work under most conditions in SQL Server (there is one internationalization setting in SQL Server where it doesn't work). The second uses SQL Server's internal standard date which works under all circumstances.
how can u produce a list of members who joined after x date f.e. after the start of the september
SELECT nameid, surname, firstname, joindate
FROM Table
WHERE joindate >= '2012-09-01';
or u can use extract function for ur condition
I have two queries offered on employee database (that we check whether they are equivalent or not), and I need to show whether we need to use IS NULL value for determining if our table would give correct result or not. We have three attributes of the salary table, which are to_date and from_date and emp_no, where by agreement to_date will have NULL if salary row is still valid (i.e. salary is still up to date for emp_no, therefore to_date is NULL).
These are queries being compared:
SELECT COUNT(*)
FROM salaries
WHERE from_date <= '1996-12-31' AND to_date >= '1996-12-01';
and
SELECT COUNT(*)
FROM salaries
WHERE from_date <= '1996-12-31' AND (to_date >= '1996-12-01' OR to_date IS NULL) ;
Goal is to find number of employees who received salary in December and only condition to receive a salary is to be employeed have salary for at least one day in December.
You are looking for employees who worked at least one day in December 1996.
This looks like a good spot to use date function overlaps():
where (from_date, coalesce(to_date, now()))
overlaps ('1996-12-01'::date, interval '1' month)
Actually the above expression has an edge cas when an employee's last day of work is December 1st (in which case I think you want to count it in, while this doesn't). So instead we could just write:
where
from_date < '1997-01-01'::date
and (to_date is null or to_date >= '1996-12-01'::date)
can somebody help me with this problem, I know I must use sysdate. For example I have entity EMPLOYEE with ATRIBUTES Emp.ID and Age.
If we supply ADD_MONTHS with a negative number it subtracts that many months from the given date. Multiplying the AGE by -12 gives us the number of months we need to subtract from the current date to derive the approximate birthday.
SELECT Emp.ID
, TO_CHAR(
ADD_MONTHS(sysdate, (Emp.Age*-12))
, 'YYYY') as year_of_birth
FROM employee Emp;
This will not be accurate as exact month is not known
SELECT id, Name, TRUNC(sysdate - age*365) as DOB FROM Employee