invail use of group function - mysql

SELECT department_id, MIN(salary)
FROM employees
WHERE department_id
HAVING AVG(salary) >= (SELECT MAX(AVG(salary))
FROM employees
GROUP BY department_id);
why it give me the invaild use of group function

If you want the minimum salary from departments whose average salary is the largest, then change the having clause:
HAVING AVG(salary) >= (SELECT AVG(salary)
FROM employees
GROUP BY department_id
ORDER BY AVG(salary) DESC
LIMIT 1
);

subquery - MAX(AVG()) you cannot do such a things, dont know what you want to achieve but if you want to hava a max of the departments averages you should do it with
SELECT MAX(avg_salary)
FROM (SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id) AS a;
or easier:
SELECT TOP 1 AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
ORDER BY AVG(salary) DESC
main query - WHERE department_id should be specified what values should department_id be or WHERE clause should be skipped
main query - lack of GROUP BY department_id
but for me this query does not have any sense...I think it would be better if you explained what do you want to calculate, probably it is achivable much easier...

Related

Count the average issue sql

I have a table with workers and their salary.
I try to count how many workers have salary bigger than the average
I know how to show the average, I know how to count how many workers the company have
but I failed to answer the question. This what I tried but I get an error:
SELECT COUNT(workers_id) FROM flight_company.workers
WHERE Salary > AVG(Salary);
If you are running MySQL 8.0, use window functions:
select avg_salary, count(*) no_workers_above_average
from (select salary, avg(salary) over() avg_salary from flight_company.workers) t
where salary > avg_salary
group by avg_salary
In earlier versions, one option is a join with an aggregate query:
select a.avg_salary, count(*) no_workers_above_average
from flight_company.workers w
inner join (select avg(salary) avg_salary from flight_company.workers) a
where w.salary > a.avg_salary
group by a.avg_salary
You can use subquery :
select count(w.workers_id))
from flight_company.workers w
where salary > (select avg(salary) from flight_company.workers);
You can do it with window function avg() (MySql 8.0+) and aggregation:
select sum(t.flag)
from (select salary > avg(salary) over () flag from workers) t
This one worked for me
SELECT COUNT(workers_id) as Num_Above_Average FROM flight_company.workersWHERE Salary > (select avg(salary) from flight_company.workers)
how do i add the average salary colume to this?
thanks

SQL GROUP BY and MIN to find people with minimum salary in each department [duplicate]

This question already has answers here:
Group by minimum value in one field while selecting distinct rows
(10 answers)
Closed 4 years ago.
I have a sql query that outputs employees who have the minimum salary across departments. It does so by finding the minimum salary for each department and finding people with salaries that match ANY of those. In this case, Person 1 can belong to department A and have a salary of 70k (even though her department's minimum is 45k) and be returned in the query if another department's minimum salary is 70k. However, what if I instead want to output names of people who have the minimum salary for their respective department (so Person 1 would not be returned anymore). Here is the current sql query:
SELECT first_name, last_name, salary, department_id
FROM employees
WHERE salary IN
( SELECT MIN(salary)
FROM employees
GROUP BY department_id
);
If you have MySQL 8.0 then the simplest approach is using window function:
SELECT *
FROM (SELECT *, RANK() OVER(PARTITION BY department_id ORDER BY salary DESC) AS r
FROM tab) sub
WHERE r = 1;
Or:
SELECT first_name, last_name, salary, department_id
FROM employees e
WHERE (department_id,salary) IN
( SELECT department_id, MIN(salary)
FROM employees
GROUP BY department_id);
Instead fo a IN clause you can also use an inner join
SELECT first_name, last_name, salary, department_id
FROM employees
INNER JOIN ( SELECT department_id, MIN(salary) min_sal
FROM employees
GROUP BY department_id
) t on t.department_id =employees.department_id
and employees.salary = t.min_sal;
this should be better for performance

How to get depatment wise max salary as well as name of employee having it?

I have table like this.
I want to find the max salary department wise and the name of employee who has it.
I ran MySql query
select concat(First_name,' ',Last_name) as Name,max(SALARY)
from Employee
group by Department;
which gives result as shown below.
In which max(SALARY) is correct but Emplyoee name is wrong.How to get both correct?
Try this:
SELECT concat(First_name,' ',Last_name) as Name,SALARY FROM Employee WHERE salary IN (SELECT MAX(SALARY) FROM Employee GROUP BY Department);
this will help you.
Here is a correct solution:
SELECT concat(e.First_name, ' ', e.Last_name) as Name, e.SALARY
FROM Employee e
WHERE salary = (SELECT MAX(SALARY) FROM Employee e2 WHERE e2.Department = e.Department);
You have to find out what the max salary is per department, and then find the employee(s) in that department who have that salary.
Use a CTE or a Correlated SubQuery.
With myCTE (dept, maxsalary)
as (
Select dept, max(salary) over (partition by dept) from EmployeeTable)
Select concat(e.firstname, e.lastname), e. salary
from EmployeeTable e where e.Dept = myCTE.dept and e.Salary = myCTE.salary
If you want only max
SELECT first_name,department,salary FROM Employees WHERE salary IN (SELECT max(salary) From employees GROUP BY department)
If you want max and min
select department, first_name, salary from employees e1 where salary in ((select max(salary) from employees where department=e1.department), (select min(salary) from employees where department=e1.department)) order by department
SELECT t.name,t.dept_id,temp.max
FROM employee as t
JOIN (SELECT dept, MAX(salary) AS max
FROM employee
GROUP BY dept_id) as temp
on t.dept_id=temp.dept_id and t.salary=temp.max

Question regarding writing SQL query

Consider I have two tables/columns:
Employee - > EmpId, DeptNo, EmpName, Salary
Department -> DeptNo, DeptName
Write a query to get employee names who is having maximum salary in all of the departments.
I have tried this:
Select max(salary),empname
from Employee
where deptno = (select deptno
from department
where deptname in('isd','it','sales')
Is it correct? Actually it's a interview question.
This is an example of groupwise max mysql pattern. One way to do it would be:
SELECT e.salary, e.name, d.deptname
FROM Employee AS e
JOIN (
SELECT max(salary) AS max_sal, deptno
FROM Employee
GROUP BY deptno
) AS d_max ON (e.salary=d_max.max_sal AND e.deptno=d_max.deptno)
JOIN Department AS d ON (e.deptno = d_max.deptno)
Though it will return more than one row for a department if more than one employee has a maximum salary in a department
Personally I'd use a cte and row_number for a question like this. For example:
with myCTE as
(
select e.empName, e.salary, d.deptName,
row_number() over (partition by e.deptNo order by e.salary desc) as rn
from Employee as e
inner join Department as d
on d.DeptNo=e.DeptNo
)
select m.empName, m.deptName, m.salary
from myCTE as m
where m.rn=1
In the case of ties (two employees in the same department have the same max salary) then this is non-deterministic (it will just return one of them). If you want to return both of them then change the row_number to a dense_rank.

How to return multiple columns when using group by in SQL

I want the names of the employees along with their salary and department who have maximum salary less than 50,000. ihave the following
SELECT department, MAX(salary) as Highest salary
FROM employees
GROUP BY department
HAVING MAX(salary) < 50000
How do I get the name of the employee to be returned?
So close...
SELECT department, name, MAX(salary) as Highest salary
FROM employees
GROUP BY department, name
HAVING MAX(salary) < 50000
After comment updates
SELECT name, department , salary
FROM employees e
JOIN
(
SELECT department as dept, MAX(salary) as HighestSalary
FROM employees
GROUP BY department
) MaxE ON e.department = MaxE.dept AND e.salary = MaxE.HighestSalary
Unless I'm misunderstanding the requirement, just add employee to the select/group by?
SELECT employee, department, MAX(salary) as Highest salary
FROM employees
GROUP BY employee, department
HAVING MAX(salary) < 50000