4

Suppose I have a query like this:

SELECT 
    s.staffID as staffID, 
    CONCAT_WS(", ", lname, fname) AS name, 
    GROUP_CONCAT(unit SEPARATOR ", ") AS units 
FROM 
    staff s, 
    units u, 
    staff_units r 
WHERE 
    s.staffID = r.staffID 
    AND u.unitID = r.unitID 
GROUP BY s.staffID 
ORDER BY lname

This gets a list something like this:

Alice    Accounting
Bob      Systems
Charlie  Customer Services, Administration

Okay so far. Now suppose that I delete the entry in staff_units that records Alice as a member of Accounting. Running this query will then yield a list from which Alice is excluded even though she still exists in the staff table:

Bob      Systems
Charlie  Customer Services, Administration

Can I adjust this SQL so that it continues to return Alice as a result, showing her as unassigned to a unit?

I could of course run one query to get a list of staff, and another query for each one of them to get current assignments. But that would mean running n+1 queries to build the list, where n is the number of staff, and that just rubs me wrong.

Will Martin
  • 4,142
  • 1
  • 27
  • 38

2 Answers2

6

You would use a LEFT JOIN

Applied to your statement, this would become

SELECT 
    s.staffID as staffID, 
    CONCAT_WS(", ", lname, fname) AS name, 
    GROUP_CONCAT(unit SEPARATOR ", ") AS units 
FROM 
    staff s
    LEFT OUTER JOIN staff_units r ON s.staffID = r.staffID     
    LEFT OUTER JOIN units u ON u.unitID = r.unitID 
GROUP BY s.staffID 
ORDER BY lname

Note that the implicit type of join you are using is becoming deprecated.

Community
  • 1
  • 1
Lieven Keersmaekers
  • 57,207
  • 13
  • 112
  • 146
1

Use LEFT OUTER JOIN. http://dev.mysql.com/doc/refman/5.0/en/join.html

So your query will be

SELECT 
    s.staffID as staffID, 
    CONCAT_WS(", ", lname, fname) AS name, 
    GROUP_CONCAT(unit SEPARATOR ", ") AS units 
FROM 
    {staff s LEFT OUTER JOIN  staff_units r ON s.staffID=r.staffID}  
rkg
  • 5,559
  • 8
  • 37
  • 50