Why does my HAVING caluse return nothing? - mysql

The problem is to find the Second Highest Salary from the employees table.
However my HAVING clause returns nothing, and I have no clue why. My logic is
I will just group by salary, and the condition I set in the HAVING clause is that
group by salary, only if salary != the maximum salary.
This way I thought I excluded the highest value for salary in the grouping, and
then I will only display the first record, which I thought would be the 2nd highest salary.
SELECT salary
FROM Employee
GROUP BY salary
HAVING salary != MAX(salary)
ORDER BY salary desc
LIMIT 1

You don't need group by, order by or limit at all, you just can take the highest salary that is smaller than the maximum:
SELECT MAX(salary)
FROM employee
WHERE salary < (SELECT MAX(salary) FROM employee);
Grouping or ordering should be avoided whenever they are not required due to their high execution time. In case the table contains very many rows, they make the query slow.

Use a subquery to get the max salary:
SELECT salary
FROM Employee
WHERE salary != (SELECT MAX(salary) FROM Employee)
ORDER BY salary desc
LIMIT 1
Grouping is not required.
You can use a join too:
SELECT MAX(a.salary)
FROM Employee a
JOIN Employee b ON b.salary > a.salary
This works because the highest salary doesn't have a row to join to and so is excluded from the result.
It trades brevity for efficiency, but unless you have millions of employees (unlikely), it will execute fast enough.

Related

I'm trying to get second heights salary but not able to fetch record from database

SELECT MAX(SALARY) FROM Employee WHERE SALARY >= (SELECT MAX(SALARY) FROM Employee);
Above is my SQL query, I try multiple time how to fetch the data of second heights salary.
But getting invalid response of query.
I'm expecting show the second heights salary from the 10k user. Those who have second heights salary. Please help to solve that. Its my task from interview.
SELECT MAX(SALARY) FROM Employee WHERE SALARY < (SELECT MAX(SALARY) FROM Employee);
replace your query

Can someone explain this SQL statement? Has to do with count function

SELECT*
FROM employee A
WHERE n-1 = (SELECT count (*)
FROM employee B
WHERE B.salary > A.salary
So I'm trying to get the nth highest salary from the employee table. This code works exactly as I want it to, but I don't understand it
particularly the 3rd line where "WHERE n-1 = (SELECT count(*)"
I understand how the count function works, but I don't get what happens when you input a number and state WHERE it equals to the count function
It looks like an example from a tutorial or book. Where it says n-1, you would substitute an integer value.
For example, if you want the 4th highest salary, you'd substitute 4-1, or 3.
So the query would be:
SELECT*
FROM employee A
WHERE 3 = (SELECT count (*)
FROM employee B
WHERE B.salary > A.salary);
The subquery that returns the count is a correlated subquery. So it searches for rows with a greater salary relative to A.salary, the salary of the respective row currently being evaluated in the outer query. This means it will run the subquery many times, once for each row of the outer query. That's usually what a correlated subquery does. It has to do that, because the result of the subquery may be different for each row of the outer query.
So this subquery will return the count of employees whose salary is greater than the salary of the respective row in the outer query. If that count is 3, then there are exactly three employees with a greater salary than the employee represented by the row A. Therefore that employee has the 4th highest salary.
In MySQL 8.0, you can use window functions, so another way to get this result without using a correlated subquery is the following:
SELECT *
FROM (
SELECT *, RANK() OVER (ORDER BY salary DESC) AS `rank`
FROM employee
) AS t
WHERE `rank` = 4;

invail use of group function

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...

MySQL- Can any one please explain this query

I want to understand the following query:
SELECT DISTINCT salary
FROM employees a
WHERE 3 >= (
SELECT COUNT(DISTINCT salary)
FROM employees b
WHERE b.salary <= a.salary
)
ORDER BY a.salary DESC;
Starting from the inner SELECT (a correlated sub-query). Such a query will be executed for each row in the outer query. So what does it do?
Return the number of unique salaries that are less than or equal to the current employee's salary.
SELECT COUNT(DISTINCT salary)
FROM employees b
WHERE b.salary <= a.salary
So, given that number for the current row of the outer select, what does that do? Return the unique salaries (in order) where the number returned from the sub-query is less than or equal to 3.
SELECT DISTINCT salary
FROM employees a
WHERE 3 >= (some number)
ORDER BY a.salary DESC;
Putting it all together, we fetch:
Unique salaries in order where such a salary is one of the worst 3.
I think that this query should return the 3 worst salaries!

How do I return the employees with salary greater than 15000?

I have two tables, EMP and Salary, where on EMP table I have the following fields:
id, emp_name,designation
And on the Salary table I have the following fields:
id, emp_id, salary
How can I get the name of employee whose salary is greater than 15000?
Use JOIN and WHERE clause
SELECT emp_name
FROM EMP
JOIN Salary
ON EMP.id = Salary.emp_id
WHERE salary > 15000
You can use an inner query, like this:
SELECT emp_name
FROM emp
WHERE id IN (SELECT emp_id FROM salary WHERE salary > 15000)
Is this homework? I will just give you the necessary hints rather than a complete statement:
The reason for salary being a table on its own is that an employee can have more than one salary. (Otherwise salary would just be a field in emp table).
So first join emp and salary to get all salaries for all employees. Then group by employees to get the sum of the salaries for each employee. Then at last filter your results to salaries over 15000. Do you know already how to filter group results?
There is more than one way to write a correct statement. I am sure you will find one using the hints given. Good luck!