Calculate the minimum salary for exempt employees and the average salary for non-exempt employees in a SINGLE SQL statement. Use subqueries to incorporate both elements in the query. It should look something like:
Min Exempt Salary Average Non-Exempt Salary
47,000 35,271
I know how to do it separate but cannot figure how to do it as it stated above , this is the statments I have.
SELECT jobs1.exempt_nonexempt_status,
Min (employees.salary)AS Minimal_Exempt_Salary
FROM employees
LEFT JOIN jobs1
ON employees.job_title = jobs1.job_title
WHERE jobs1.exempt_nonexempt_status = 'Exempt'
GROUP BY jobs1.exempt_nonexempt_status
SELECT jobs1.exempt_nonexempt_status,
Avg (employees.salary)AS Average_Non_Exempt_Salary
FROM employees
LEFT JOIN jobs1
ON employees.job_title = jobs1.job_title
WHERE jobs1.exempt_nonexempt_status = 'Non-exempt'
GROUP BY jobs1.exempt_nonexempt_status
Try this:
SELECT
MIN(CASE WHEN J.exempt_nonexempt_status = 'Exempt'
THEN E.Salary
END) AS Minimal_Exempt_Salary,
SUM(CASE WHEN J.exempt_nonexempt_status = 'Non-exempt'
THEN E.Salary
END) AS Average_Non_Exempt_Salary
FROM Employees E
LEFT JOIN JOBS1 J ON J.job_title = E.job_title
WHERE J.exempt_nonexempt_status IN ('Exempt', 'Non-exempt')
A normal way to do this would be:
select j.exempt_nonexempt_status
, avg(case when j.exempt_nonexempt_status='Non-exempt' then e.salary end)
as Average_Non_Exempt_Salary
, min(case when j.exempt_nonexempt_status='Exempt' then e.salary end)
as Minimal_Exempt_Salary
from Employees e
left join
jobs1 j
on e.job_title = j.job_title
group by
j.exempt_nonexempt_status
But that doesn't use subqueries. Another way is to wrap your two queries in an outer select:
select (
select MIN (employees.salary)
from Employees left join jobs1
on employees.job_title = jobs1.job_title
where jobs1.exempt_nonexempt_status='Exempt'
group by jobs1.exempt_nonexempt_status
) as MinimalExemptSalary
, (
select avg (employees.salary)
from Employees left join jobs1
on employees.job_title = jobs1.job_title
where jobs1.exempt_nonexempt_status='Non-exempt'
group by jobs1.exempt_nonexempt_status
) as AverageNonExemptSalary
Related
I'm messing around in my school's database and I am trying to count the null values in this query:
SELECT Depart_ID, DepartName,
COUNT(Name) AS employees,
SUM(Salary) AS 'Total salary'
FROM Ch4Employee AS E
INNER JOIN Ch4Department AS D
ON E.Depart_ID = D.ID
GROUP BY Depart_ID, DepartName
Any tips?
If you want to count NULL salaries, do count(*) - count(salary), because count(*) counts all rows, and count(salary) counts the non-null values.
E.g.
SELECT Depart_ID, DepartName,
COUNT(Name) AS employees,
SUM(Salary) AS 'Total salary',
COUNT(*) - COUNT(Salary) AS null_salaries
FROM Ch4Employee AS E
INNER JOIN Ch4Department AS D
ON E.Depart_ID = D.ID
GROUP BY Depart_ID, DepartName
select Depart_ID, DepartName, COUNT(Name) as employees, SUM(Salary) as 'Total salary' from Ch4Employee AS E
inner join Ch4Department as D on E.Depart_ID = D.ID
group by Depart_ID, DepartName
HAVING COUNT(Name) = 0
If you want to check the values after aggregation you have to use Having.
I have a query with NOT IN clause,need to convert into join statement.
SELECT EMP_NBR
FROM employees not in (select emp_id from departments where dept_id = 10 and division = 'sales')
I think the proper transformation would be a left join:
select EMP_NBR
from employees e join
departments d
on e.dept_id = d.dept_id and
d.dept_id = 10 and
d.division = 'sales'
where d.dept_id is null;
Note: I added what I consider to be correct JOIN conditions.
not in could be mimicked in SQL using just not in the where clause, e.g.
SELECT EMP_NBR FROM employees inner join department on
employees.emp_id =departments.emp_id
where NOT (dept_id = 10 and division = 'sales')
I am trying to work out how to count the number of female and male employees from the total number of employees and put them in separate columns next to the total number of employees. Here is my code:
select cd.dept_no, d.dept_name, count(cd.dept_no) as 'No. Current
Employees', e.gender from current_dept_emp as cd
inner join departments as d on cd.dept_no = d.dept_no
inner join employees as e on e.emp_no = cd.emp_no
where cd.to_date = '9999-01-01'
group by cd.dept_no, e.gender
order by cd.dept_no
It is returning the following result
How do I get my desired output?
Use conditional aggregation:
select cd.dept_no, d.dept_name,
count(*) as num_current,
sum(case when e.gender = 'M' then 1 else 0 end) as num_males,
sum(case when e.gender = 'F' then 1 else 0 end) as num_females
from current_dept_emp cd inner join
departments d
on cd.dept_no = d.dept_no inner join
employees e
on e.emp_no = cd.emp_no
where cd.to_date = '9999-01-01'
group by cd.dept_no
order by cd.dept_no;
The following query I tried...
select d.deptID, max(tt.total)
from dept d,
(select d.deptID, d.deptName, sum(days) as total
from vacation v, employee e, dept d
where v.empId = e.empID
and d.deptID = e.deptID
group by d.deptID, d.deptName) tt
where d.deptID = tt.deptID
group by d.deptName;
--having max(tt.total);
Try using limit since your inner query already does the calculation.
select TOP 1 * from (
select d.deptID, d.deptName, sum(days) as total
from vacation v, employee e, dept d
where v.empId = e.empID
and d.deptID = e.deptID
group by d.deptID, d.deptName)
order by total desc;
Depends on the dbms you're using.. this is for mysql
In oracle use where rownum = 1
In sql server use SELECT TOP 1 *
Using Top:
Select top 1 with ties * from
(Select D.DepartmentName, sum(V.Days) as SumDays
from Vacations V
inner join Employee E on E.EmployeeID=V.EmployeeID
inner join Department D on D.DepartmentID=E.DepartmentID
group by D.DepartmentName)SumDays
Order by SumDays desc
Try like this,
SELECT TOP 1 d.departmentname,
Sum(v.days) AS vacations
FROM employee emp
INNER JOIN department d
ON d.departmentid = emp.departmentid
INNER JOIN vacations v
ON v.employeeid = emp.employeeid
GROUP BY d.departmentname
ORDER BY 2 DESC
I have two tables employees, salary_advance.
employees table has columns empid, name, salary and salary_advance has id, empid, amount, date
I want to show name, salary, remaining for all employees ..
remaining = ( salary - amount )
when I do inner join I get only employees who take advance ..
I want to show who take advance + other employees in employees ..
This is my SQL statement
select
employees.name , employees.salary ,
(employees.salary - salary_advance.amount )
from
employees
inner join
salary_advance on employees.empid = salary_advance.empid
You'll need to use a LEFT OUTER JOIN instead of your INNER JOIN, and you'll also want to use ISNULL to get a 0 instead of NULL from the salary_advance table:
SELECT
employees.name,
employees.salary,
Remaining = (employees.salary - ISNULL(salary_advance.amount, 0) )
FROM
employees
LEFT OUTER JOIN
salary_advance ON employees.empid = salary_advance.empid
If an employee can have more than one advance, you'll want to use a LEFT JOIN with SUM and GROUP BY to get the correct result. If you need to count only advances since a certain date, add that to the ON clause of the LEFT JOIN;
SELECT employees.name , employees.salary ,
(employees.salary - COALESCE(SUM(salary_advance.amount),0)) remaining
FROM employees
LEFT JOIN salary_advance
ON employees.empid = salary_advance.empid
AND salary_advance.date >= '2012-01-01'
GROUP BY employees.name, employees.salary
An SQLfiddle to test with.
Also you can use:
SELECT
employees.name,
employees.salary,
( CASE salary_advance.amount
WHEN NULL THEN employees.salary
ELSE employees.salary - salary_advance.amount
END
) Remaining
FROM
employees
LEFT OUTER JOIN
salary_advance ON employees.empid = salary_advance.empid
Use a left join, and take care of the null values:
select
e.name , e.salary,
employees.salary - isnull(a.amount, 0)
from
employees e
left outer join
salary_advance a on e.empid = a.empid
The isnull function might be named ifnull, depending on what database you are using.
Print this:
select
employees.name,
employees.salary,
Remaining = (employees.salary - ISNULL(salary_advance.amount, 0) )
from
employees
left outer join
salary_advance on employees.empid = salary_advance.empid
instead of this:
select
employees.name , employees.salary ,
(employees.salary - salary_advance.amount )
from
employees
inner join
salary_advance on employees.empid = salary_advance.empid
Summary: You need to use a left outer join instead of inner join
Try this:
select
employees.name , employees.salary ,
Remaining = (employees.salary - ISNULL(salary_advance.amount, 0))
from
employees
left join
salary_advance on employees.empid = salary_advance.empid
The LEFT JOIN keyword returns all rows from the left table, with the matching rows in the right table.