SQL: Joining to two tables and then using sum() and count() - mysql

If I have two tables:
school:
school_id | class_id | school_location
-------------------------------------------
400 50 Arizona
staff:
staff_id | forename | school_id | wage
------------------------------------------
1 Peter 400 5000
How could I get the output the number of staff that work in school and the salary of each school.
For example:
school_id | numberofstaff | salary
---------------------------------------
400 | 1 | 5000
I know I should join the tables like so:
SELECT school_id
FROM school
INNER JOIN staff
ON school.school_id = staff.school_id
However I am unsure how to do the remaining part of the query.
SELECT numberofstaff COUNT(numberofstaff) from staff
GROUP BY school_id
Union all
select 'SUM' numberofstaff, COUNT(numberofstaff)
FROM staff
This should give me my school ids with the number of staff belonging to each school_id.

Once you join both tables, you can then count the staff and sum all the wages for each school:
SELECT sc.school_id,
COUNT(*) as numberofstaff,
SUM(st.wage) as salary
FROM school sc
INNER JOIN staff st
ON sc.school_id = st.school_id
GROUP BY sc.school_id

try this way
SELECT COUNT(staff.numberofstaff) as numberofstaff , school.school_id as school_id FROM school
INNER JOIN staff
ON school.school_id = staff.school_id
GROUP BY school.school_id;

Related

SQL select query to get total unique entries from two foreign key tables based on a column value

I've got three tables as shown below - ideally it wouldn't be laid out like this but currently no power change it.
Team User Member
ID | Name ID | TeamId | Email ID | TeamId | Email
----------
1 | Team A 1 | 1 | a#email.com 1 | 1 | a#email.com
2 | Team B 2 | 1 | b#email.com 2 | 1 | b#email.com
3 | Team C 3 | 1 | c#email.com
I need to be able to get the combined count of users and members in each team, uniquely based on their email address.
So for example, Team A would have a unique count of combined members and users of 3.
An entry may exist in either the user table OR the member table, or in both for each email.
The outcome of the query would be TeamName and TotalUsers.
Any help with this type of query would be greatly appreciated.
Use UNION to collect all the distinct combinations of team ids and emails from User and Member and do a LEFT join of Team to that resultset and aggregate:
SELECT t.id, t.name,
COUNT(email) count
FROM Team t
LEFT JOIN (
SELECT teamid, email FROM User
UNION
SELECT teamid, email FROM Member
) e ON e.teamid = t.id
GROUP BY t.id;
you can UNION members and User table, so that duplicates would be removed
And then join it to the temas table
SELECT
t1.Name, COUNT(DISTINCT Email)
FROM
Team t1
JOIN
( SELECT TeamId , Email FROM User
UNION SELECT TeamId , Email FROM Member) t2 ON t2.TeamId = t1.ID
GROUP BY t1.Name

How do I join two tables in SQL to grab the names from one table and show them in a query?

I have two tables like this:
Employee Table:
EmployeeID
firstName
lastName
1
Johnny
Depp
2
Rebecca
Smith
3
Rodger
Doe
Sales Table:
EmployeeID
Sales
1
100.20
2
200.19
3
355.23
And I'd like to join the tables to do something like this:
EmployeeID
fullName
Sales
1
Johnny Depp
100.20
2
Rebecca Smith
200.19
3
Rodger Doe
355.23
How would I do that? Here's what I tried so far:
SELECT employee.firstName + employee.lastName AS fullName, employeeID, sales
FROM employee i
INNER JOIN Sales s ON s.customerID = i.CustomerID
I'm getting a syntax error at my "+" symbol.
What's my problem?
as #Gordon said ,use CONCAT():
SELECT CONCAT(employee.firstName, ' ', employee.lastName) AS fullName
, employeeID
, sales
FROM employee i
INNER JOIN Sales s
ON s.customerID = i.CustomerID

aggregate tables with AVG

I am new to SQL.
I checked "another solutionSQL JOIN two tables with AVG" posted in StackOverflow. And I don't get the meaning with this line in that article:AVG(score.score * 1.0) Besides, the alternative solution below doesn't work at all:
SELECT songs.id, songs.song, songs.artist,
(SELECT AVG(Score) FROM score WHERE score.id = songs.id) AS AvgScore)
FROM songs
Here are my tables:
[employees]
Dep ID | SALARY
1 | 500
2 | 200
1 | 300
2 | 1000
2 | 400
3 | 200
3 | 300
[departments]
Dept ID Dep| Dept Name
1 | Volcano
2 | ShootingStar
3 | Tsunami
In the end, I want to create a list looks like:
Dept Name | Average Salary
Volcano | $$$
ShootingStar| $$
Tsunami | $$$$
I tried various ways and hunting hints in stackoverflow for sub queries/inner join features but still can't get it.
Based on the solution in the previous link SQL JOIN two tables with AVG, this code works:
-- mapping DEPT ID with NAME + average salary by DEPT --
select EMPLOYEES.DEP_ID, DEPARTMENTS.DEP_NAME, AVG(EMPLOYEES.SALARY) as AVG_S
from EMPLOYEES
LEFT JOIN DEPARTMENTS
ON EMPLOYEES.DEP_ID = DEPARTMENTS.DEPT_ID_DEP
group by DEP_ID, DEP_NAME;
However, I want to understand the reason WHY my original one doesn't work?
select E.DEP_ID, D.DEP_NAME, (select AVG(SALARY) from EMPLOYEES group by DEP_ID) as AVG_S
from EMPLOYEES E, DEPARTMENTS D
where E.DEP_ID = D.DEPT_ID_DEP
group by DEP_ID, DEP_NAME;
Please help!
Thank you very much.
The query you wanted to write:
select
e.dep_id,
d.dep_name,
(select avg(salary) from employees e where e.dep_id = d.dept_id_dep) as avg_s
from departments d;
The logic of the query is to select from departments only, then use a correlated subquery to compute the average salaries of employees of the department. This avois aggregating in the outer query.
Your query fails in the following regards:
table employees is in the from clause of the outer query
the outer query does group by
the subquery is not corelated on the department

Pull associated user_id from id field multiple times in query

I have a table where I'm pulling in a "manager" and his associated "employees" however I'm having some problems getting the syntax correct.
My table structure:
Managers:
User_ID | User_Name
1 | jay
2 | matt
3 | john
4 | Employee1
5 | Employee2
6 | Employee3
Employees:
Parent_ID | Employee_ID
1 4
1 5
1 6
So what you see here is I want to pull in all the employees for a particular manager.
Attempted query:
select managers.user_name
from managers
ifnull(group_concat(distinct(employees.employee_id) SEPARATOR ';'), 'Nobody Under You') "Employees"
left join employees on employees.employee_id=managers.id
group by managers.user_name
I would like for it to have:
jay --> Employee1; Employee2; Employee3
But instead it has:
jay --> 4;5;6
My problem is instead of the employee ID I want their associated user_name... can someone assist?>
Odd that you've got the employees in the Managers table but in any case, you need to join again to the same table. For example
SELECT
Managers.User_Name,
COALESCE(GROUP_CONCAT(emp.User_Name SEPARATOR ';'), 'Nobody Under You') AS 'Employees'
FROM Managers
LEFT JOIN Employees ON Managers.User_ID = Employees.Parent_ID
LEFT JOIN Managers emp ON Employees.Employee_ID = emp.User_ID
GROUP BY Managers.User_Name
SQL Fiddle ~ http://sqlfiddle.com/#!9/698e5d/7

select ids that doesn't have a specific values

I have a table with the schema below:
+---------+--------+
|studentId | course |
+---------+--------+
|1 | 2 |
|1 | 3 |
|1 | 4 |
|1 | 5 |
|2 | 4 |
|2 | 5 |
+---------+--------+
and I want to perform a query to get student Ids that don't have course 2 and 3
select * from students where course not in (2,3);
but it returns Students IDs 1 and 2 and I want it to return Student ID 2 only.
How do I do that?
You could do it like this:
select * from students where studentId not in -- exclude all students from course 2 & 3
(
--find all the students in course 2 & 3
select distinct studentId --could be duplicates might as well grab a distinct list.
from students
where course in (2,3)
)
This answers assumes that OP wants to filter out students that have either course 2 or course 3 or both of them set.
At first, find all students, who have course 2 or 3
SELECT DISTINCT studentId
FROM students
WHERE course IN (2,3)
Then, find all students, who are not in that list
SELECT *
FROM students
WHERE studentId NOT IN (...)
If you only want to return a list of studentIds, without their courses, replace * with DISTINCT studentId.
Put those together:
SELECT DISTINCT studentId
FROM students
WHERE studentId NOT IN (
SELECT DISTINCT studentId
FROM students
WHERE course IN (2,3)
)
Another query using having to filter out students that have courses 2 or 3
select studentId
from students
group by studentId
having sum(course in (2,3)) = 0
This should work:
select
*
from
students s
where
not exists ( select
1
from
students ss
where
ss.studentID = s.studentID
and ss.course in (2,3));
SELECT DISTINCT x.studentid
FROM student x
LEFT
JOIN
( SELECT studentid
FROM student
WHERE course IN(2,3)
GROUP
BY studentid
HAVING COUNT(*) = 2 ) y
ON y.studentid = x.studentid
WHERE y.studentid IS NULL;
(of course, it's highly unlikely that a table holding students and courses would be called student. enrolment might be a better title)
I would recommend using NOT IN and writing a subquery that pulls for each student who is taking courses 2 or 3. That is, if you are looking for students who are not taking course 2 or 3. If you are looking to exclude students who are taking BOTH courses, this will need to change a little bit. Let me know if that is the case.
Start by writing the subquery, which is easy enough:
SELECT *
FROM students
WHERE course = 2 OR course = 3
Then, you can select from your table again using the NOT IN operator:
SELECT DISTINCT studentid
FROM students
WHERE studentid NOT IN (SELECT studentid
FROM students
WHERE course = 2 OR course = 3);
And it works!
JR's query will perform poorly MySQL < 5.6 and only performs an OR not an AND on course.
Try this:
SELECT
id
FROM foo AS missingfoo
LEFT JOIN (
SELECT id FROM foo AS foo1
JOIN foo AS foo2 USING (id)
WHERE foo1.course=2
AND foo2.course=3
) AS z
USING (id) WHERE z.id IS NULL GROUP BY id;