How do constant values effect the ON clause of Joins?

If person table is:

id  name

1   Person One
2   Person Two
3   Person Three
4   Person Four
5   Person Five

If manager table is

id  name
-1  Admin
2   Manager One
3   Manager Two

if the query is:

SELECT DISTINCT *
FROM Person LEFT JOIN Manager 
ON (Manager.id = Person.id OR Manager.id = -1)

Then the result is:

Person One  -1  Admin
Person Two  -1  Admin
Person Two  2   Manager One
Person Three    -1  Admin
Person Three    3   Manager Two
Person Four -1  Admin
Person Five -1  Admin

Here all person rows joins with the -1 Admin (on manager table) AND if the same id exist in manager table one more join occurs.


Unless there a row in the Manager table where the id is equal to -1, it does nothing at all. If there is such a row, then that row will always be joined to every row in the person table. So for each Person row you would potentially get two ros in query output, one with manager.id = to the persons' id, and another with the Manager.ID = -1 row


Also you will see the AND clause used to further filter the records. This is extremely important in dealing with outer joins as adding those filtering actions to the where clause will turn the join from a left join to an inner join (unless it is something like where t.idfield is null).

Below I show how this works and why it important to put the filtering clauses in the right place.

create table #test ( test1id int, test varchar (10)) create table #test2 ( test2id int, test1id int, test2 varchar (10))

insert into #test (test1id, test)
select 1, 'Judy'
union all
select 2, 'Sam'
union all 
select 3, 'Nathan'

insert into #test2 (test2id, test1id, test2)
select 1,1,'hello'
union all 
select 2,1,'goodbye'
union all 
select 3,2,'hello'

select * from #test t
left join #test2 t2 on t.test1id = t2.test1id
where test2 = 'goodbye'
--result set
--test1id   test    test2id test1id test2
--1 Judy    2   1   goodbye

select * from #test t
left join #test2 t2 on t.test1id = t2.test1id
and test2 = 'goodbye'
--result set 
--test1id   test    test2id test1id test2
--1 Judy    2   1   goodbye
--2 Sam NULL    NULL    NULL
--3 Nathan  NULL    NULL    NULL

You can use where some field is null (assuming you pick a field that will never be null) to grab the records in the first table but not the second like so:

select * from #test t
left join #test2 t2 on t.test1id = t2.test1id
where test2id is null
--result set 
--test1id   test    test2id test1id test2
--3 Nathan  NULL    NULL    NULL