i have to sort the employees in the EMPLOYEE table by the following rule: when their department is SALES, sort by experience, otherwise sort by SALARY
this is what i have tried :
select FNAME||' '||LNAME as emp_name,salary,HIRE_DATE from employee
where dept_id=(select dept_id from department where name='SALES') order by HIRE_DATE asc;
UNION
select FNAME||' '||LNAME as emp_name,salary,HIRE_DATE from employee
where dept_id NOT IN (select dept_id from department where name='SALES') order by salary desc;
which throws an error because of two orders i think. Any solutions?
try this:
select FNAME||' '||LNAME as emp_name,salary,HIRE_DATE from employee E
join department D
on E.dept_id=D.dept_id
order by (case when D.name='SALES' then HIRE_DATE end),
(case when D.name<>'SALES' then salary end) desc
Sales department is displayed first, sorted by hire_date. Other departments are displayed next ordered by salary.
select FNAME||' '||LNAME as emp_name,salary,HIRE_DATE
from employee
inner join department
on employee.dept_id = department.dept_id
order by
-- Sales department is on top. Swap 0 and 1 if you want sales on bottom
case when department.name = 'SALES'
then 0
else 1
end,
-- And employees are sorted by hire_date
case when department.name = 'SALES'
then employee.HIRE_DATE
else null
end,
-- Employees from other departments are sorted by salary
employee.Salary desc
use decode:
SELECT fname || ' ' || lname AS emp_name
,salary
,hire_date
FROM employee e
,department d
WHERE e.dept_id = d.dept_id
ORDER BY decode(d.name,'SALES',experience,salary)
;
see also http://sqlfiddle.com/#!4/afa6f/1
SELECT e.fname||' '||e.lname as emp_name, e.salary, e.hire_date
FROM employee e, department d
WHERE e.dept_id = d.dept_id
ORDER BY
CASE
WHEN d.name ='SALES' then
hire_date ASC
ELSE
salary DESC
END
OK. Apologies, try this - probably been answered already tho.
Related
SELECT
employee_id,
department_id,
first_name,
last_name,
hire_date,
job_id
FROM employees e
WHERE hire_date IN
(
SELECT max(hire_date)
FROM employees
WHERE e.department_id = department_id
)
ORDER BY hire_date ASC
Result of the query
So this is my query and the result of it. There are two tied results for SA_REP department and I should have only one result - for instance the one with the lower employee_id. I've googled the problem but can't seem to find any related results...
Thanks for any help!
You can use a not exists query which gives you more flexibility:
SELECT *
FROM employees e
WHERE NOT EXISTS ( -- no x exists that...
SELECT *
FROM employees x
WHERE x.department_id = e.department_id -- belongs to same department
AND (
x.hire_date > e.hire_date OR -- but hired later than e
x.hire_date = e.hire_date AND x.employee_id < e.employee_id -- hired on same date but has lesser employee id than e
)
)
You may use the RANK analytic function here:
WITH cte AS (
SELECT e.*, RANK() OVER (PARTITION BY department_id
ORDER BY hire_date DESC, employee_id) rnk
FROM employees e
)
SELECT employee_id, department_id, first_name, last_name, hire_date, job_id
FROM cte
WHERE rnk = 1;
I want to display the lowest earning employees of each department based on salary using min().
I have tables of employees with id, first name, last name, department id, salary
and departments, department_id, name department id from 1 to 5.
I am having trouble doing this, I only know how to start
SELECT name, surname from employees WHERE...
You would use min() for this. You would use window functions:
select e.*
from (select e.*,
rank() over (partition by department_id order by salary) as seqnum
from employees e
) e
where seqnum = 1
order by department_id;
With rank()over() ranking window function you can have your rows within a group ranked as you wish. Here we have ranked all the employees starting with lowest salary in a department. Now if we select rows with rn =1 then it will select employees from a department with lowest salary.
Then joined the result with department table to get the name of the
With lowestEarningEmployees as
(
id, first_name, last_name, department_id, salary, rank()over(partition by department_id order by salary)rn from employees
)
select le.id, le.first_name, le.last_name, le.department_id,d.name, le.salary,
from lowestEarningEmployees le inner join departments d on le.department_id=d.department_id
** If more than one employee in a department have lowest salary all of them will be selected. If you want to select only one employee with lowest salary then you need to use row_number() instead of rank().
You can also use subquery to have your desired result (Though I would suggest to use first one) :
Select e.id, e.first_name, e.last_name, e.department_id, d.name, e.salary
from employees e inner join department d on e.department_id = d.department_id
where e.salary=(select min(salary) from employees empl where e.department_id=empl.department_id)
I am trying to compile a query which gives me the highest salary per each department and for each unique employee. The complexity is that 1 employee can be part of multiple departments.
In case the same employee has the highest salary in several departments, only the department with a lower salary should show. This is my start but I am not sure how to continue from here:
select max(salary) as salary, dd.dept_name,d.emp_no
from salaries s
inner join dept_emp d on
s.emp_no=d.emp_no
inner join departments dd on
d.dept_no=dd.dept_no
group by 2,3;
My output is:
What should I modify from here?
For an employee, you seem to only want to include the department with the smallest salary. I would recommend using window functions:
select s.*
from (select s.*,
rank() over (partition by dept_name order by salary desc) as seqnum_d
from (select s.*, d.dept_name,
rank() over (partition by dept_name order by salary) as seqnum_ed
from salaries s join
dept_emp d
on s.emp_no = d.emp_no join
departments dd
d.dept_no = dd.dept_no
) s
where seqnum_ed = 1
) s
where seqnum_d = 1;
Something like this?
select m.salary, m.emp_no, salary.dept_name from salary,
(select emp_no, min(salary) salary from salary group by emp_no) m
where
m.emp_no=salary.emp_no and m.salary=salary.salary;
Having two tables
Employee
Id
Name
Salary
DepartmentId
and
Departament
Id
Name
How can I get the highest average salary within two tables
like
Joe and Max belong to dept 1 so, avg is (70K+90K)/2
= 80K
and
Henry and Sam belog to dept 2, avg is (80K + 60K)/2=70k
so How to select the greatest avg salary by depto?, in this case
IT 80K
i have been trying:
'group the salary by each department and use the Max function to obtain the highest one.
select
Department.Name as Department,
T.M as Salary
from
Employee,
Department,
(select DepartmentId as ID, Max(Salary) as M from Employee group by DepartmentId) as T
where
Employee.Salary = T.M and
Department.Id = T.ID and
Employee.DepartmentId = Department.Id
enter image description here
If multiple department having same maximum avg salary then this solution will return multiple rows.
SELECT *
FROM(
SELECT d.Id, d.Name, AVG(e.Salary) avg_salary, RANK() OVER(ORDER BY AVG(e.Salary) DESC) AS rank_
FROM Employee e
INNER JOIN Departament d ON e.DepartmentId = d.Id
GROUP BY d.Id, d.Name
)T
WHERE rank_ = 1
If you want to get the average just for the department, you can use in this way.
select DepartmentId as ID, de.name as Deptname, Avg(Salary) as M from Employee em1
join Department de on de.departmentID = em1.DepartmentId
group by DepartmentId, de.name
If you want employee name along with highest average then you can use this approach as well.
select
Deptname as Department,
e.Name as Employeename,
z.M as Salary
from
Employee e
join
( select DepartmentId,Deptname, M, row_number() (order by m desc) rownum from ( select DepartmentId as ID, de.name as Deptname, Avg(Salary) as M from Employee em1
join Department de on de.departmentID = em1.DepartmentId
group by DepartmentId, de.name) as T) z
on
e.DepartmentId = T.DepartmentId and z.rownum = 1
If you want a full answer, you should provide DDL, sample data and desired result.
If I understand you correctly, you are looking for something like:
SELECT DepartmentID, AVG(Salary) AS AverageSalaryForDept
FROM Employee
GROUP BY DepartmentID
ORDER BY AverageSalaryForDept DESC;
This will give you all the averages, ordered from the highest to the lowest. Now if you want just the top one, add a FETCH clause:
SELECT DepartmentID, AVG(Salary) AS AverageSalaryForDept
FROM Employee
GROUP BY DepartmentID
ORDER BY AverageSalaryForDept DESC
OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY;
HTH
I am trying to figure this out but I keep getting this error. I know it has something to do with the subqueries in the SELECT and HAVING clauses but I have no idea how to fix them. Any help would be greatly appreciated.
department table: https://gyazo.com/f9d782abd428acc7ec2e7d5d59befad7
employee table: https://gyazo.com/b2d7d792c0933b13d6fdd7166fffb8a6
expected output: https://gyazo.com/41f6a5626a5827acbe76e3c41287742d
EDIT: I figured out an alternative syntax! Thanks for all the help!
CURSOR c_emp (p_total_emp NUMBER) IS
SELECT department.DEPARTMENT_NAME
, MAX(employee.HIRE_DATE)
, (SELECT COUNT(EMPLOYEE_ID)
FROM employee
HAVING HIRE_DATE = MAX(HIRE_DATE))
, ROUND(MAX(employee.SALARY))
, ROUND(MAX(employee.SALARY) * 0.68)
, (SELECT COUNT(EMPLOYEE_ID)
FROM employee
HAVING SALARY > ROUND(MAX(employee.SALARY) * 0.68))
FROM employee
INNER JOIN department
ON employee.DEPARTMENT_ID = department.DEPARTMENT_ID
GROUP BY 1
HAVING (SELECT COUNT(EMPLOYEE_ID)
FROM employee
HAVING SALARY > ROUND(MAX(employee.SALARY) * 0.68)) > p_total_emp
ORDER BY DEPARTMENT_NAME ASC
;
sample:
Hoping you're having a great week so far. :)
Just a heads up on the query, you are experiencing the error because you can't GROUP BY 1. You need to GROUP BY columns that you're not aggregating. (eg. department.DEPARTMENT_NAME) like the following:-
CURSOR c_emp (p_total_emp NUMBER) IS
SELECT department.DEPARTMENT_NAME
, MAX(employee.HIRE_DATE)
, (SELECT COUNT(EMPLOYEE_ID)
FROM employee
HAVING HIRE_DATE = MAX(HIRE_DATE))
, ROUND(MAX(employee.SALARY))
, ROUND(MAX(employee.SALARY) * 0.68)
, (SELECT COUNT(EMPLOYEE_ID)
FROM employee
HAVING SALARY > ROUND(MAX(employee.SALARY) * 0.68))
FROM employee
INNER JOIN department
ON employee.DEPARTMENT_ID = department.DEPARTMENT_ID
GROUP BY department.DEPARTMENT_NAME
HAVING (SELECT COUNT(EMPLOYEE_ID)
FROM employee
HAVING SALARY > ROUND(MAX(employee.SALARY) * 0.68)) > p_total_emp
ORDER BY DEPARTMENT_NAME ASC
;