How to get second highest salary department wise? - mysql

Suppose we have some employees in each department.we have total 3 departments . Below is the sample source table named 'employee'
emp dept_id salary
A 10 1000
B 10 2000
C 10 3000
D 20 7000
E 20 9000
F 20 8000
G 30 17000
H 30 15000
I 30 30000
j 30 30000
k 30 17000
Here may same salary is exist in same department.
I use Wamp-server which has mysql-5.7.23
And I want to like:
B 10 2000
F 20 8000
G 30 17000

I think there are several way to solve the problem. Following solution from my side and works fine.
SELECT *
From employee e2
WHERE e2.salary = (SELECT distinct salary FROM employee where dept_id=e2.dept_id order by salary desc limit 1,1);
I need only second highest salary value with department wise which is the input array of next operation in my project. Finally I use
SELECT e2.dept_id, max(e2.salary)
From employee e2
WHERE e2.salary = (SELECT distinct salary FROM employee where dept_id=e2.dept_id order by salary desc limit 1,1)
group by e2.dept_id

Related

LIMIT and Group By? How do I return the lowest 100 earning customers by country? SQL

Hi I’ve a table database1
3 columns : customer_id , income , country
Customer_id
1001
1002
...
Income
5000
6000
7000
Country
SG
HK
VN
...
How do I write a query that returns the lowest 100 earning customers per country?
Is it possible to return:
Customer ID | country code
1003 SG
1004 SG
...
1007 VN
...
So on
Thanks!
On mySQL 8 you can leverage a window function for this:
SELECT * FROM
(
SELECT
country,
customer_id,
row_number() over(partition by country order by income asc) earn_rank
FROM table
)x
WHERE x.earn_rank <= 100
You can conceive that this window function will sort the rows by country then by income, then start counting up from 1. Each time the country changes the row numbering starts over from 1 again. This means that for every country there will be a row numbered 1 (with the lowest income), and a 2, 3 etc. If we then wrap it up in another outer query that selects only rows where the number is less than 101 we get 100 rows per country

How to get the count of the people have a better salary than the current tuple

I was working on a problem from Leetcode #185
I could understand the solution but I want to know how to write the query that add a column which indicate the count the people have a better salary than the tuple one. I think it is possible in SQL, but i don't know how to make it right, i always get syntax error. :-/
from Employee e1 (Select count(distinct e2.Salary)
from Employee e2
Where e2.Salary > e1.Salary) as c
For exemple I have such a table Employee:
Id - Name - Salary
1 toto 60000
2 tata 50000
3 kiki 90000
4 lily 70000
5 momo 60000
I want to have such a result:
Id - Name - Salary - Head_count_of_higher_salary
1 toto 60000 2
2 tata 50000 4
3 kiki 90000 0
4 lily 70000 1
5 momo 60000 2
Thanks guys
Your subquery is almost correct.
Just remove DISTINCT from COUNT() (although just COUNT(*) would also work) and use it as the new column:
select *,
(
select count(e2.Salary)
from Employee e2
where e2.Salary > e1.Salary
) as Head_count_of_higher_salary
from Employee e1
See the demo.
You can also implement this type of query with a LEFT JOIN on the joined table having a higher salary than the first, and then counting the number of rows in the joined table:
SELECT e1.Id, e1.Name, e1.Salary, COUNT(e2.Id) AS Head_count_of_higher_salary
FROM Employee e1
LEFT JOIN Employee e2 ON e2.Salary > e1.Salary
GROUP BY e1.Id, e1.Name, e1.Salary
Output:
Id Name Salary Head_count_of_higher_salary
1 toto 60000 2
2 tata 50000 4
3 kiki 90000 0
4 lily 70000 1
5 momo 60000 2
Demo on SQLfiddle
If you are running MySQL 8.0: what you ask for is exactly what rank() does.
This would be as simple as:
select e.*, rank() over(order by salary desc) - 1 head_count_of_higher_salary
from employees e

Find row wise max from two different columns with update function

Can anyone help me with UPDATE with max?
TABLE-A
EMP SALARY BONUS
A 100 110
B 50 80
C 30 20
D 80 50
E 30 40
I want Answer like
TABLE-A
EMP SALARY BONUS MAX
A 100 110 110
B 50 80 80
C 30 20 30
D 80 50 80
E 30 40 40
You could use GREATEST(MySQL):
UPDATE tableA
SET `max` = GREATEST(Salary, Bonus);
I would suggest adding computed column to avoid updating in the future:
CREATE TABLE tableA(Emp INT, Salary INT, BONUS INT,
`max` INT AS (GREATEST(Salary, Bonus)));
Rextester Demo
SQL Server you could use a CASE STATEMENT
select
EMP,
SALARY,
BONUS,
[Max] = case when Salary > Bonus then Salary else Bonus end
from
TABLE-A
Or on the update...
UPDATE TABLE-A
SET [Max] = case when Salary > Bonus then Salary else Bonus end
For SQL Server 2012+:
UPDATE TABLE_A
SET [MAX] = IIF (SALARY > BONUS, SALARY, BONUS);

Need help solving this SQL query to understand

write an sql to generate the report for employee dataset with give condition if average age >35 then states value is ok else notok dataset
id name age dept salary
1 tt 51 it 4000
2 kk 56 it 6000
3 mm 45 sales 7000
4 kk 25 sales 9000
5 op 24 hr 4000
6 op 24 hr 8000
output
dept avgage states
it 53.5 ok
sales 35 ok
hr 24 notok
Use this query.
SELECT a.dept,
a.avgage,
CASE
WHEN a.avgage >= 35 THEN 'ok'
ELSE 'notok'
END states
FROM (SELECT dept,
Avg (age) avgage
FROM employee
GROUP BY dept) a
ORDER BY avgage DESC;
Note: Please show some effort to understand and write a query on your own.

SELECT MAX() FROM TABLE using GROUP BY

I have some table:
name dep_id salary
Vasia 5 1000
Oleg 5 1300
Vitia 4 1000
Sacha 3 1100
Kolia 5 1600
Lesha 2 1400
Sergey 4 1200
Marina 5 1300
Olga 5 1500
Igor 4 1400
Valia 3 1500
Erema 4 1500
I need to get the name of the employees with the maximum salary in his department
i.e I need
Lesha 1400
Valia 1500
Erema 1500
Kolia 1600
I tried:
SELECT name, max(salary) FROM employees GROUP BY dep_id
but this displays incorrect values
how can I do this?
select e1.*
from employees e1
join
(
SELECT dep_id, max(salary) as msal
FROM employees
GROUP BY dep_id
) e2 on e1.dep_id = e2.dep_id
and e1.salary = e2.msal
select t1.name,t2.sallary
from Employees t1 join
(select dep_id,MAX(Sallary) as Sallary
from Employees
group by dep_id) t2 on t1.dep_id=t2.dep_id and t1.sallary=t2.sallary
order by t2.sallary
Result:
name Sallary
---------------
Lesha 1400
Valia 1500
Erema 1500
Kolia 1600
Demo in SQL Fiddle
Try Below Query for the required output :
select name,sallary from employees t1 where (dep_id,sallary) in
(select dep_id,max(sallary) from employees group by dep_id);