Search code examples
sqljoinforeign-keysone-to-manymany-to-one

SQL Join Query multiple One-to-many? or many-to-many?


Hopefully this will be an easy question!

I have two tables, a 'client(s)' table and an individual 'names' table. The basis is that a client can have one or two(max) names. I structured them like this so that each 'name' can have a different title. The tables are:

clients
+------------+-------------+------------+
| clientID   | nameID1     | nameID2    |
+------------+-------------+------------+
|          1 | 1           | 2          |
|          2 | 3           |            |
|          3 | 4           |            |
+------------+-------------+------------+


names 
+------------+-------------+------------+------------+
| nameID     | surname     | initials   | titleID    |
+------------+-------------+------------+------------+
|          1 | Banks       | P          | 1          |
|          2 | Smith       | W          | 2          |
|          3 | Wilson      | BT         | 2          |
|          4 | Jefferson   | JP         | 3          |
+------------+-------------+------------+------------+

Where titleID is retrieved from...

titles 
    +------------+-------------+
    | titleID    | titleName   |
    +------------+-------------+
    |          1 | Mr          |
    |          2 | Mrs         |
    |          3 | Miss        |
    +------------+-------------+

So for instance clientID = 1 is Mr P Banks '&' Mrs W Smith

The problem is I'm not familiar with querying to get that answer above.

I cannot try:

SELECT
clientID, names.surname, names.initials, titleName
FROM clients, names, titles
WHERE titleID = titleID AND
NameID1 = nameID AND
NameID2 = nameID

How do I correctly join the tables in a query to find, e.g., clientID 1 = Mr P Banks '&' Mrs W Smith


Solution

  • You need to join to the Names (and Titles) table twice, once for nameID1, and once for nameID2. I've assumed that the client must have at least one name hence nameID1 is INNER JOIN, and since namedID2 is optional (nullable) it is LEFT OUTER JOIN.

    SELECT c.clientID, n1.surname, n1.initials, t1.titleName, n2.surname, n2.initials, t2.titleName
    FROM clients c
    INNER JOIN names n1 ON nameID1 = n1.nameID
    INNER JOIN titles t1 ON n1.titleID = t1.titleID
    LEFT OUTER JOIN names n2 ON nameID2 = n2.nameID
    INNER JOIN titles t2 ON n2.titleID = t2.titleID