I am trying to get the maximum salary for each year in a table with the attributes teamID, salary, yearID. Shouldn't be hard right? Here is my query:
SELECT teamID, MAX(tS.teamSalary), yearID
FROM
(SELECT
teamID,
sum(salary) AS teamSalary,
yearID
FROM salaries
GROUP BY teamID, yearID) tS
GROUP BY yearID;
The inner query works just fine, but the outer one is just reporting the first teamID for each group. What am I doing wrong?
Inner query output:
A 1 2000
B 1 2000
C 2 2000
A 2 2001
B 3 2001
A 2 2002
B 2 2002
Full query output:
A 1 2000
A 2 2001
A 2 2002
Desired output:
C 2 2000
B 3 2001
A 2 2002
First you get maxSalary by year, then you get the extra information:
SELECT teamID, salary, yearID
FROM salaries
JOIN
(SELECT MAX(salary) AS maxSalary,
yearID
FROM salaries
GROUP BY yearID) tS
ON ts.yearID = salaries.yearID
AND ts.maxSalary = salaries.salary
EDIT: Not sure if you want the max salary of some year, then to which team it belongs, or if you want the max salary by team and year. The second option is here:
SELECT MAX(salary) AS maxSalary, yearID, teamID
FROM salaries
GROUP BY yearID, teamID
Related
This question already has answers here:
Get top n records for each group of grouped results
(12 answers)
Closed 1 year ago.
Let's say I have this table called Employees:
Id
Name
Salary
DepartmentId
1
Joe
85000
1
2
Henry
80000
2
3
Sam
60000
2
4
Max
90000
1
5
Janet
69000
1
6
Randy
85000
1
7
Will
70000
1
And for each department id, I want the top three salaries. So the result should be:
DepartmentId
Name
Salary
1
Max
90000
1
Joe
85000
1
Randy
85000
1
Will
70000
2
Henry
80000
2
Sam
60000
So for each department id, the top three salaries are returned, and if there are duplicate salaries in the top three, the duplicates are returned too and the limiting factor is top three unique salaries. How to implement this?
You would use dense_rank():
select e.*
from (select e.*,
dense_rank() over (partition by departmentid order by salary desc) as seqnum
from employees e
) e
where seqnum <= 3;
WITH cte AS (
SELECT DepartmentId,
Salary,
ROW_NUMBER() OVER (PARTITION BY DepartmentId ORDER BY Salary DESC) rn
FROM Employees
)
SELECT *
FROM Employees
WHERE Salary >= ( SELECT MIN(Salary)
FROM cte
WHERE Employees.DepartmentId = cte.DepartmentId
AND rn <= 3 )
it is well described in manuals and references, but you haven't even linked any of the manuals or provided any information at all in your answer. – Martin
MySQL 8.0 Reference Manual / ... / WITH (Common Table Expressions)
MySQL 8.0 Reference Manual / ... / Window Function Descriptions # ROW_NUMBER() function
MySQL 8.0 Reference Manual / ... / Subqueries # Correlated Subqueries
I have a table emp with columns :-
empid empname mgrid doj
1 Steve 2 25-03-2019
2 Winter 3 26-04-2019
3 Summer 1 27-05-2019
4 Autumn 2 28-06-2019
and a table sal with columns :-
empid project salary
1 P1 1000000
2 P1 60000
3 P2 5000
4 P3 1000000
I want to list name of employees with same salary.
Desired result :-
first_employee second_employee salary
Steve Autumn 1000000
What I tried to do is join emp table with sal and before that was trying to self join sal table. How can I achieve the desired results also is there a way to use union in order to get the results.
What if there are more than two employees with the same salary?
I would recommend group_concat():
select salary, group_concat(empname order by doj) as empnames
from emp
group by salary
having count(*) > 1;
I have two related tables:
(1) people contains names and image files.
(2) cities contains cities they have visited.
people
id name image
1 John NULL
2 Carrie 001.jpg
3 Desmond 002.jpg
4 Harry 003.jpg
5 Paul NULL
cities
id city people_id year_visited
1 Chicago 1 2000
2 Chicago 4 2000
3 Chicago 5 2001
4 Paris 1 2000
5 Paris 2 2002
6 Chicago 4 2002
7 Chicago 1 2001
8 London 1 2004
9 Sydney 5 2001
10 Sydney 1 2002
11 Rio 5 2002
12 London 5 2004
13 Sydney 5 2003
14 Sydney 5 2005
I would like to identify all people without an image, and the city they have visited the most. So the results I am looking for is:
name most_visited_city number_of_visits
John Chicago 2
Paul Sydney 3
I can group_concat the cities they have visited, but not drill down to the single city they visited the most.
All help gratefully appreciated.
The following gets people, cities, and the count:
select p.id, c.city, count(*) as cnt
from people p join
cities c
on p.id = c.people_id
where p.image is null
group by p.id, c.city;
Getting information about the most visited is tricky in MySQL. Here is one method that works if the data is not too large:
select id,
substring_index(group_concat(city order by cnt desc separator '|'), '|', 1) as most_visited_city,
max(cnt) as number_of_times_visited
from (select p.id, c.city, count(*) as cnt
from people p join
cities c
on p.id = c.people_id
where p.image is null
group by p.id, c.city
) pc
group by id;
This query should return the most visited city for each people_id in cities.
SELECT t1.people_id, t2.city, t2.visits
FROM (
SELECT people_id, MAX(visits) AS max_visits
FROM (
SELECT people_id, city, COUNT(*) AS visits
FROM cities
GROUP BY people_id, city) x
GROUP BY people_id) AS t1
JOIN (
SELECT people_id, city, COUNT(*) AS visits
FROM cities
GROUP BY people_id, city) AS t2
ON t1.people_id = t2.people_id AND t1.max_visits = t2.visits
The general structure is based on an answer in SQL Select only rows with Max Value on a Column, but instead of getting the max value of a column in the table, it's using the max value in the subquery that counts visits per city. Unfortunately, it results in an ugly query because you have to repeat that subquery, since MySQL doesn't have CTEs.
Then you can join it with people to get the person's name and filter out the ones with an image.
SELECT p.name, t2.city, t2.visits
FROM (
SELECT people_id, MAX(visits) AS max_visits
FROM (
SELECT people_id, city, COUNT(*) AS visits
GROUP BY people_id, city) x
GROUP BY people_id) AS t1
JOIN (
SELECT people_id, city, COUNT(*) AS visits
GROUP BY people_id, city) AS t2
ON t1.people_id = t2.people_id AND t1.max_visits = t2.max_visits
JOIN people AS p ON p.id = t1.people_id
WHERE p.image IS NULL
DEMO
This is my employee table
empid name Date_of_joining
1 dilip 2010-01-30
2 suresh 2001-03-01
3 ramesh 2003-01-01
I want to get the number of employees with total employees group by employee date of joining
expected output
year new joining total employees
2001 10 10
2002 12 22
2003 15 27
query
select YEAR(`DATE_OF_JOINING`) as 'year', COUNT(*) as 'count1',sum(count(*)) from employee
GROUP BY YEAR(`DATE_OF_JOINING`)
You need a running total using a user defined variable.
You need a derived table cause running totals don't work with group by statement
SET #SUM = 0;
SELECT
YEAR,
NoOfEmployee AS newJoining,
(#SUM := #SUM + NoOfEmployee) AS totalJoining
FROM (
SELECT
YEAR(Date_of_joining) AS YEAR,
COUNT(*) AS NoOfEmployee
FROM
employees
GROUP BY
YEAR(Date_of_joining)
) O
here a sample
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);