Here's an example of the left join to inner join problem. This is a made up example, but I hope it clearly illustrates the problem.
First, set up the data:
Code:
Declare @Recipe Table(RecipeId Int, FoodId Int)
Insert Into @Recipe Values(1, 100)
Insert Into @Recipe Values(1, 101)
Insert Into @Recipe Values(1, 102)
Declare @Food Table(FoodId Int, Description VarChar(20))
Insert Into @Food Values(100, 'Bread')
Insert Into @Food Values(101, 'Peanut Butter')
Declare @FoodColor Table(FoodId Int, Color VarChar(20))
Insert Into @FoodColor Values(100, 'White')
Insert Into @FoodColor Values(102, 'Red')
Now, suppose we want to get all of the recipe items and any matches that exist in the food table. We could write a query like this:
Code:
Declare @Recipe Table(RecipeId Int, FoodId Int)
Insert Into @Recipe Values(1, 100)
Insert Into @Recipe Values(1, 101)
Insert Into @Recipe Values(1, 102)
Declare @Food Table(FoodId Int, Description VarChar(20))
Insert Into @Food Values(100, 'Bread')
Insert Into @Food Values(101, 'Peanut Butter')
Declare @FoodColor Table(FoodId Int, Color VarChar(20))
Insert Into @FoodColor Values(100, 'White')
Insert Into @FoodColor Values(102, 'Red')
Select *
From @Recipe R
Left Join @Food F
On R.FoodId = F.FoodId
The results are this:
[tt][blue]
RecipeId FoodId FoodId Description
----------- ----------- ----------- --------------------
1 100 100 Bread
1 101 101 Peanut Butter
1 102 NULL NULL
[/blue][/tt]
Notice that the recipe table has a row with foodid = 102, but that row does not exist in the food table. It's still included in the results because we used a left join. But also notice the 2nd FoodId column. This is actually the value from the "right" table (@Food). It contains a NULL. If we then inner join to another table on this NULL value, there will NOT be a match and the row will be removed from the results. Like this:
Code:
Set NOCOUNT ON
Declare @Recipe Table(RecipeId Int, FoodId Int)
Insert Into @Recipe Values(1, 100)
Insert Into @Recipe Values(1, 101)
Insert Into @Recipe Values(1, 102)
Declare @Food Table(FoodId Int, Description VarChar(20))
Insert Into @Food Values(100, 'Bread')
Insert Into @Food Values(101, 'Peanut Butter')
Declare @FoodColor Table(FoodId Int, Color VarChar(20))
Insert Into @FoodColor Values(100, 'White')
Insert Into @FoodColor Values(102, 'Red')
Select *
From @Recipe R
Left Join @Food F
On R.FoodId = F.FoodId
Inner Join @FoodColor FC
On F.FoodId = FC.FoodID
The results are:
[tt][blue]
RecipeId FoodId FoodId Description FoodId Color
-------- ------ ------ -------------- ------ --------
1 100 100 Bread 100 White
[/blue][/tt]
Notice that we now only have 1 row. Why? Well, the food id of the 2 missing rows was 101 and NULL. Notice that the FoodColor table does not have a row where FoodId = 101, so that row was eliminated. As for the other row, the NULL, NULLS don't match with anything so that row is also eliminated.
Now, let's look at the same query but changing the inner join to a left join:
Code:
Set NOCOUNT ON
Declare @Recipe Table(RecipeId Int, FoodId Int)
Insert Into @Recipe Values(1, 100)
Insert Into @Recipe Values(1, 101)
Insert Into @Recipe Values(1, 102)
Declare @Food Table(FoodId Int, Description VarChar(20))
Insert Into @Food Values(100, 'Bread')
Insert Into @Food Values(101, 'Peanut Butter')
Declare @FoodColor Table(FoodId Int, Color VarChar(20))
Insert Into @FoodColor Values(100, 'White')
Insert Into @FoodColor Values(102, 'Red')
Select *
From @Recipe R
Left Join @Food F
On R.FoodId = F.FoodId
[!]Left[/!] Join @FoodColor FC
On F.FoodId = FC.FoodID
This time the results are:
[tt][blue]
RecipeId FoodId FoodId Description FoodId Color
-------- ------ ------ ----------- -------- ---------
1 100 100 Bread 100 White
1 101 101 Peanut Butter NULL NULL
1 102 NULL NULL NULL NULL
[/blue][/tt]
I hope this contrived example helps you to understand why inner joining to a table that was already left joined to can cause problems. Any questions, just ask.
-George
Microsoft SQL Server MVP
My Blogs
SQLCop
"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom