How to write an SQL query for this scenario? - sql

I have a table containing attributes Id, Emp_name, dept_name, salary. Now i want to write an SQL query that will give me the dept_name value for which the overall salary of all employees belonging to that department is the highest, i.e dept for which sum of salaries of all its employees is the highest...? If there is any similar question with answer on stackoverflow, please suggest.. I dint find one. Thanks :)
I tried group by with sum() function, but i could not get how to find the maximum and compare it with sum.

Can you do
SELECT TOP 1 dept_name FROM table GROUP BY dept_name ORDER BY SUM(salary) DESC

Seems like a textbook example for GROUP BY:
select dept_name, total_salary from (
Select dept_name, sum(salary) as total_salary
from my_table
group by dept_name
) order by total_salary desc

try this:
select top 1 dept_name from myTable group by dept_name order by sum(salary) desc

SELECT dept_name FROM table
GROUP BY dept_name
ORDER BY SUM(salary) DESC
LIMIT 1
And you would also better have you departments in another table linked to the first table via foregn keys. Just a note.

I don't know exactly know your requirements, but perhaps there is another point to be considered: Two (or more) departments could have the same sum of salary.
I have not tested the query, but this should give you all departments which have the maximum some of salary:
select dept_name FROM table_name GROUP BY dept_name HAVING SUM(salary)=(select MAX(sum_salary) FROM (select SUM(salary) AS sum_salary FROM table_name GROUP BY dept_name))

Related

How can I find minimum among average salary of department table using groupby? (In SQL)

I am learning SQl and I have a question in mind as follow:
I want to find minimum among the avg(salaries) of department.
Schema:
Department(dno, salary)
==================================================
what I tried is below query but I got error.
**select min(avg(salary)) from department groupby dno;**
Can anyone help me out with this, or any other possible solution?
Using TOP 1:
select top 1 avg(salary) AS avg_salary
from department
group by dno
order by avg_salary
Using a select from subquery approach:
select min(T.avg_salary) as min_salary
from
(
select avg(salary) as avg_salary
from department
group by dno
) T;
conceptually, both min and avg are a set operation. pendantically, the min(avg(salary)) == avg(salary), because, there's only one avg for a given set of numbers. You could obviously, calculate
select min(salary), avg(salary) from department
This would tell you the smallest salary in the depeartment which would by definition be less than the avg unless all the salaries would be the same. Which is an odd use case.
You might be thinking of something like:
select department, min(salary), max(salary), avg(salary)
from employee
group by department
To understand a new distrubution I will often use
select min(targetValue), max(targetValue), avg(targetvalue) from targetTable
To get a sense for the range in values.

basic sql employee

The employee table (EMP) specifies groups by department code, the sum of salaries by group, the average (constant treatment), and the number of people in each group's salary, and is presented below, listed in department code order. I would like to modify the following SQL syntax to look up departments whose average salary exceeds 2800000.
SELECT
DEPT
, SUM(SALARY) 합계
, FLOOR(AVG(SALARY)) 평균
, COUNT(*) 인원수
FROM
EMP
GROUP BY
DEPT
ORDER BY DEPT ASC;
question 1. Conditions that need to be modified
question 2. What should I add to the presented code?
I can't read your aliases so I'll just presume what they mean.
If query - you posted in the question - works OK, then use it as a CTE and select desired data from it:
with data as
(select dept,
sum(salary) sumsal,
floor(avg(salary)) avgsal,
count(*) cnt
from emp
group by dept
)
select *
from data
where avgsal > 2800000;
you can use below sql:
SELECT
DEPT
, SUM(SALARY) 합계
, FLOOR(AVG(SALARY)) 평균
, COUNT(*) 인원수
FROM
EMP
GROUP BY
DEPT having FLOOR(AVG(SALARY) > 2800000
ORDER BY DEPT ASC;
You can filter aggregated result using having
SELECT
DEPT
, SUM(SALARY) 합계
, FLOOR(AVG(SALARY)) 평균
, COUNT(*) 인원수
FROM
EMP
GROUP BY DEPT
HAVING AVG(SALARY) >2800000
ORDER BY DEPT ASC;

Select data using condition from AVG expression in HR table

I try to learn mysql oracle database, I want to show average salary from table employee group by department_id and where average salary is like '%0'.
here is my query
select department_id, AVG(salary) as "Pay Salary per dept"
from employees
where department_id is not null and AVG(salary) like '%0'
group by department_id order by department_id
what's right query to replace
AVG(salary) like '%0' ?
Thanks
Use MOD function instead of LIKE.
where MOD(salary,10)=0
query
select t.dept_id,t.Pay_Salary_per_dept
from
(
select dept_id, AVG(salary) as Pay_Salary_per_dept
from employee
where dept_id is not null
group by dept_id
)t
where mod(t.Pay_Salary_per_dept,10)=0
order by t.dept_id;
Fiddle demo here
To filter the result of aggregated functions there is the HAVING clause in SQL.
You may write it direct without a subquery as follows:
select dept_id, AVG(salary) as Pay_Salary_per_dept
from employee
where dept_id is not null
group by dept_id
having mod(AVG(salary),10)=0
;

Using the MIN function in the having clause

I want to get the name of the employee who has the minimum salary. Is there a way to do this using only one query? I have given my query below, it doesn't work because the having clause requires a condition. Is there any way to give a condition in the having clause that will retreive the employee name with the minimum salary?
SELECT first_name,min(salary) as "sal"
FROM Employees
GROUP BY first_name
having min(salary);
How about using ROWNUM?
SELECT *
FROM(SELECT first_name, salary
FROM Employees
ORDER BY salary
) WHERE ROWNUM = 1
SELECT first_name, salary as "sal"
FROM employees
WHERE salary =(SELECT MIN(salary)
FROM employees);
Try this solution, inspired from here:
SELECT e1.first_name, e1.salary AS "sal"
FROM Employees e1
LEFT OUTER JOIN Employees e2
ON (e1.id <> e2.id AND e1.salary > e2.salary)
WHERE e2.id IS NULL;
With a single SELECT statement:
SELECT MIN( first_name ) KEEP ( DENSE_RANK FIRST ORDER BY salary ASC, first_name ASC ) AS first_name,
MIN( salary ) KEEP ( DENSE_RANK FIRST ORDER BY salary ASC, first_name ASC ) AS salary
FROM Employees;
SQLFIDDLE
However, if there are multiple people with the same minimum salary then this will only get the one with the name which is first alphabetically.
You can get all the names, but it does require multiple SELECT statements:
SELECT first_name, salary
FROM Employees
WHERE salary = ( SELECT MIN(salary) FROM Employees );
But having multiple SELECT statements isn't a bad thing.
SQLFIDDLE
SELECT TOP 1 WITH TIES *
FROM employees
ORDER BY salary ASC
If you need the employee with the lowest salary why don't you use Order By ..
SELECT top 1 first_name,min(salary) as LowestSalary
FROM Employees order by Salary asc
SELECT first_name,min(salary) as "sal"
FROM Employees
GROUP BY first_name
having min(salary) >0;
If you want to do this with only one query, while also retrieving all employees with the minimum salary (example: you have a minimum salary of $40,000, but two employees have this exact salary) you could join the table with itself. This solution also uses the 'having' clause that you included in your original question.
SELECT e.first_name,e.salary AS "sal"
FROM Employees e, Employees e2
GROUP BY first_name
HAVING MIN(e2.salary)=e.salary;

SQL finding the maximum of all averaged results

I have the relation instructor(ID, name, dept_name, salary).
How would I go about finding the name of the department with the highest average salary?
looks like a job for the HAVING clause
will this do the trick?
select top 1 id, name, avg (salary)
from instructor
group by id, name
order by avg (salary) desc
Given the homework tag, I won't spell it out for you, but you want to look into the AVG function and the GROUP BY clause.
select top 1 dept_name, avg(salary) as AvgSalary
from instructor
group by dept_name
order by AvgSalary desc
This will get you both if two deparments have the same average salary, use rownum=1 if this is not needed.
with averages as (select dept_name,avg(salary) aver from instructor group by dept_name)
select dept_name
from averages
where aver = (select max(aver) from averages)