Postgres multiple joins

Postgresql

Postgresql Problem Overview


This is a postgres db. I am attempting to pull dog breed names (Cane Corso, Labrador, etc) from a breed table, to display based on the foreign keys located in an animal table. My issue is the animal table has two foreign keys to this single breed table, and I keep getting errors with my query. The first breed name will return based on a left join, but the second I cannot get the name to display as I already have a left join. Below is a simplified outline of what I am attempting to do:

breed table (ID, BreedName)
animal table (ID, breedID, breed2ID)

SELECT animal.ID, breed.BreedName FROM animal LEFT JOIN breed ON animal.breedID=breed.ID WHERE animal.ID='7';

What I need to do is also get the BreedName to join for animal.breed2ID which I am failing miserably at. I could easily hard code the breed names and have it display in the application, but this is not conducive to changes, additions, or deletions of breed names in the database.

Postgresql Solutions


Solution 1 - Postgresql

just do another join on that same table:

SELECT animal.ID, breed1.BreedName as BreedName1, breed2.BreadName as BreadName2 
FROM animal 
   LEFT JOIN breed as breed1 ON animal.breedID=breed1.ID 
   LEFT JOIN breed as breed2 ON animal.breedID=breed2.ID 
WHERE animal.ID='7';

Solution 2 - Postgresql

While Ivan has solved your issue for your current database design a long term consideration or just a thing to learn from would be to make your table design more normalized so that having to add a new join every time you want to add a breed to an animal is not necessary. Through this simple design you have actually made your life more difficult.

When you see repeated property types on an entity, in your case breedID and breed2ID you should typically start to smell something rotten in all but a very few rare cases.

Under the ideal design you would do the following.

1.Keep your breed as is.

2.Make animal look like something like animal(animal_id,animal_name).

3.Add a new animal_breed table. It would look like this animal_breed(animal_breed_id,animal_id,breed_id). With animal_bread_id being a pk and a unique key on (animal_id,breed_id) with foreign keys pointing back to the respective tables.

This design allows a given animal to take on one or more breed types with out ever having to mess with your query to return the multiple breeds back. Your current design becomes a nightmare every time you have an animal with an extra breed. It has the potential to kill performance and make maintenance a nightmare and on top of it just isn't sound database design.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1137376View Question on Stackoverflow
Solution 1 - PostgresqlkingdaemonView Answer on Stackoverflow
Solution 2 - PostgresqlKuberchaunView Answer on Stackoverflow