Pull associated user_id from id field multiple times in query - mysql

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

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

MySQL gruop by when there is no aggregation

I have a table called booking_details.
id | tour_id | tour_fee| booking_id
1 | 1 | 200 | 1
2 | 2 | 350 | 1
3 | 1 | 200 | 2
4 | 2 | 350 | 3
tour_id refers to the Tours table and the booking_id refers Bookings table.
I want to get a report like this
tour_id 1 refers to New york tour
tour_id 2 refers to Paris tour
I need a generate a report something like this
tour name | total_income | number_of_bookings
New york tour| 400 | 2
Paris tour | 700 | 2
Here basicaly tour name, total income from that tour and number of bookings for that tour.
What I have done upto now is this. But this gives me a syntax error. It seems I can't group by results.
SELECT booking_details.*,Tours.name as name, count(Tours.id) FROM booking_details
inner join Tours on
booking_details.tour_id = Tours.id group by Tours.name;
How do I achive this using MySQL?
you have used aggregation count() in your query and from your requirement, it shows you need aggregation. when you used aggregation you have to put selection column in group by also
SELECT Tours.name as name,sum(tour_fee) income, count(Tours.id)
FROM booking_details
inner join Tours on
booking_details.tour_id = Tours.id group by Tours.name
As you used in selection booking_details.* which means every column of booking table but you have not put those column in group by so it thrown error
You are trying to select non aggregated columns which are not part of your GROUP BY clause.
Change your query like following.
SELECT t.NAME AS NAME,
Sum(bd.tour_fee) total_income,
Count(t.id) number_of_bookings
FROM booking_details bd
INNER JOIN tours t
ON bd.tour_id = t.id
GROUP BY t.NAME;
Small suggestion, as a good practice you should use alias names for tables when joining.
You need to add all other columns in group by except aggregated fields
SELECT
booking_details.tour_id,
Tours.name AS name,
SUM(tourfee) AS total_income,
COUNT(Tours.id)
FROM
booking_details
INNER JOIN
Tours ON booking_details.tour_id = Tours.id
GROUP BY
booking_details.tour_id, Tours.name

SQL Select parent as column name and child as value

I am creating a database to store music.
There are different categories that each have sub categories. Example:
id name parentID
1 instrumentation null
2 solo_instrument null
3 Concert Band 1
4 Brass Band 1
5 Fanfare Band 1
6 Clarinet 2
7 Saxophone 2
8 Trumpet 2
On the other hand I have a table that stores the musicID that is linked to a categoryID
id categoryID musicID
1 4 1
2 8 1
3 3 2
4 6 2
I need the following result from a query:
musicID instrumentation solo_instrument
1 Brass Band Trumpet
2 Concert Band Clarinet
I have been told to use a tree structure as in the future it is likely that other categories are added and this should be able to support that. However, I am not able to figure out how to write a query to get the result above.
I kind of get the result I want when selecting first the instrumentation, second the solo_instrument, but this is all hardcoded and does not allow for music tracks to only have one parentID as I select them individually.
Is this even possible or should I overhaul my database structure? I'd like to see your recommendations.
You should be able to tackle this using conditional aggregation.
Query :
SELECT
mu.musicID,
MAX(CASE WHEN cp.name = 'instrumentation' THEN ca.name END) instrumentation,
MAX(CASE WHEN cp.name = 'solo_instrument' THEN ca.name END) solo_instrument
FROM
musics mu
INNER JOIN categories ca ON ca.id = mu.categoryID
INNER JOIN categories cp ON cp.id = ca.parentID
GROUP by mu.musicID
The INNER JOINs pull up the corresponding category, and then goes up one level to find the parent category. If new root categories are created, you would just need to add more MAX() columns to the query.
In this DB Fiddle demo with your sample data, the query returns :
| musicID | instrumentation | solo_instrument |
| ------- | --------------- | --------------- |
| 1 | Brass Band | Trumpet |
| 2 | Concert Band | Clarinet |
First you group by musicid in table_music and the join twice to table_categories:
select t.musicid, c1.name instrumentation, c2.name solo_instrument
from (
select musicid, min(categoryid) instrumentationid, max(categoryid) solo_instrumentid
from table_music
group by musicid
) t inner join table_categories c1
on c1.id = t.instrumentationid
inner join table_categories c2
on c2.id = t.solo_instrumentid
order by t.musicid

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

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;

Join multiple columns on MySQL table

I am trying to join multiple columns on a MySQL table. I can't figure out how I can retrieve multiple columns into one single row, so I can display one row on my page.
table: employee_timesheet
id employee_id service_area_name sign_off_1 sign_off_2 sign_off_3 created_date status last_updated
1 2 London Rom Director NULL 2015-02-11 17:22:44 Submitted 2015-02-11 17:22:44
table (empty): employees_timesheet_sign_off_team_leaders
id employee_id timesheet_id sign_off_key team_leader_id
table: employees_timesheet_sign_off_roms
id employee_id timesheet_id rom_id sign_off_key
1 2 1 4 sign_off_1
2 2 1 5 sign_off_1
table: team_leaders
id first_name last_name email reports_to status date_added last_updated
2 Bob Test me#mydomain.com 4 Active 2015-02-03 12:50:25 2015-02-03 13:28:56
table: roms
id first_name last_name email status date_added last_updated
4 Bill Gates bill#mydomain123445678.com Active 2015-02-03 13:14:07 2015-02-03 13:28:40
5 Ben Morris ben#mydomain123445678.co.uk Active 2015-02-11 17:35:43 NULL
I need to join the above tables to get the following result:
ID: 1
Team Leader: (null)
Rom: Bill Gates,Ben Morris
Date: 2015-02-11 17:22:44
It would be very much appreciated if someone could help with this.
Thanks in advance.
For your use case, you need to use the GROUP_CONCAT function: http://www.percona.com/blog/2013/10/22/the-power-of-mysqls-group_concat/. The query would look something like:
SELECT et.id, CONCAT(l.first_name, ' ', l.last_name) 'team_leader', GROUP_CONCAT(DISTINCT CONCAT(r.first_name, ' ', r.last_name)), et.last_updated
FROM employee_timesheet et
INNER JOIN employees_timesheet_sign_off_roms etr ON et.id = etr.timesheet_id
INNER JOIN roms r ON etr.rom_id = r.id
LEFT JOIN employees_timesheet_sign_off_team_leaders etl ON et.id = etl.timesheet_id
LEFT JOIN team_leaders l ON etl.team_leader_id = l.id
GROUP BY et.id, team_leader, et.last_updated