Reputation: 55
Desired output : I want to select all titles of employees who in 1991 had a higher salary than the average in 1991.
Current code :
USE employees;
SELECT t.title
FROM employees emps INNER JOIN
employees.salaries s
ON s.emp_no = emps.emp_no INNER JOIN
employees.titles t
ON t.emp_no = s.emp_no
WHERE s.from_date LIKE '1991%' AND s.salary >
Employees table:
CREATE TABLE employees (
emp_no INT NOT NULL,
birth_date DATE NOT NULL,
first_name VARCHAR(14) NOT NULL,
last_name VARCHAR(16) NOT NULL,
gender ENUM ('M','F') NOT NULL,
hire_date DATE NOT NULL,
PRIMARY KEY (emp_no)
Salaries table:
CREATE TABLE salaries (
emp_no INT NOT NULL,
salary INT NOT NULL,
from_date DATE NOT NULL,
to_date DATE NOT NULL,
FOREIGN KEY (emp_no) REFERENCES employees (emp_no) ON DELETE CASCADE,
PRIMARY KEY (emp_no, from_date)
Titles table:
CREATE TABLE titles (
emp_no INT NOT NULL,
title VARCHAR(50) NOT NULL,
from_date DATE NOT NULL,
to_date DATE,
FOREIGN KEY (emp_no) REFERENCES employees (emp_no) ON DELETE CASCADE,
PRIMARY KEY (emp_no,title, from_date)
The from_date in the salaries table has to be used.
Upvotes: 3
Views: 1007
Reputation: 94859
First of all there is time range in the salary table. A person can have worked all 1991 for one salary. That would be the case for instance for a person who worked from 1989 till 2000 for the same salary. But a person can also have worked part of the year for one salary and the other part for another salary (e.g. a salary rise in July). And a person may have started in December 1, 1991. Or quit on January 15, 1991. How do you want to calculate the average?
Let's say you simply count all salary records in 1991. E.g. person A worked in January for 1000 and the rest of the year for 3000, person B worked all year for 1000 and person C only worked in June for 2000 and in July for 4000. The calculation: (1000 + 3000 + 1000 + 3300 + 3700) / 5 = 2400. The persons who worked in 1991 for a higher salary than 2400 are A and C.
select *
from titles
where emp_no in
(
select emp_no
from salaries
where from_date <= date '1991-12-31' and to_date >= date '1991-01-01'
and salary >
(
select avg(salary)
from salaries
where from_date <= date '1991-12-31' and to_date >= date '1991-01-01'
)
);
You may want to restrict the titles to 1991, too. I don't know. Maybe you even want them to match the time spans where the salary was higher than the average. In that case you'd have to look for overlapping time ranges. (Example 1: Salary rise in June, new title in July would be two titles for the high salary. Example 2: New title in June, salary rise in July would be one title with the high salary.)
If you have MySQL 8.0 you can use a WITH
clause to select the 1991 salaries to get the query more readable.
Upvotes: 2
Reputation: 28834
avg_salary_in_1991
field, allowing comparisons.where
, so that the employee salary
should be greater than the computed avg_salary_in_1991
.Try the following:
USE employees;
SELECT t.title
FROM employees AS emps
INNER JOIN employees.salaries AS s ON s.emp_no = emps.emp_no
INNER JOIN employees.titles AS t ON t.emp_no = s.emp_no
CROSS JOIN (SELECT AVG(s2.salary) AS avg_salary_in_1991
employees.salaries AS s2
WHERE YEAR(s2.from_date) = 1991) AS avg_sal_1991
WHERE YEAR(s.from_date) = 1991 AND
s.salary > avg_sal_1991.avg_salary_in_1991
Upvotes: 0