tags:

views:

269

answers:

3

I want to left join TableA to TableB where a certain condition in tableA is true So I do this type of SQL query

Select * from
TableA Left Join TableB on TableA.fld1 = TableB.fld2
where TableA.fld3 = True

This works OK. Now however I want to do the Join only with certain records in TableB, ie those records in TableB where a certain condition is met, specifically fld4 has false as its value. The reason I want to do this is I want to know which rows in tableA don't have a match in tableB among the rows in tableB where fld4 is false.

If I was to delete all the rows in TableB where fld4 is true and run the above query I'd get the correct result. All I'd need to do is find the rows in the resultant recordset with null in some cell. But if instead of deleting rows from TableB first I alter the query to the one below I get no rows at all returned

Select * from
TableA Left Join TableB on TableA.fld1 = TableB.fld2
where TableA.fld3 = True
and TableB.fld4 = false

If my ramblings make sense can someone tell me what I'm doing wrong? Thanks

+5  A: 

You should put the condition in the join clause. When you have a where clause that filters rows on the "right" side of a left join query, you ultimately exclude rows. Try this:

Select * 
from   TableA 
       Left Join TableB 
         on TableA.fld1 = TableB.fld2 
         and TableB.fld4 = false
where  TableA.fld3 = True
G Mastros
great thanks very much!
jjb
+1  A: 

Put it in the join clause:

select * from TableA 
left join TableB 
  on TableA.fld1 = TableB.fld2 
 and TableB.fld4 = False
where TableA.fld3 = True

Edit: ah, I missed this:

I want to know which rows in tableA don't have a match in tableB among the rows in tableB where fld4 is false.

Joel's query would work, but since you are not interested in any rows from TableB, a correlated subquery may be cleaner:

select * from TableA
where TableA.fld3 = True 
  and not exists (
    select * from TableB
    where TableA.fld1 = TableB.fld2
      and TableB.fld4 = False
    )
Peter
thank you for the super quick response!
jjb
Thanks peter, it won't be easy for me but I need to try to get my head around the concept of subqueries.
jjb
Accepting this as this solved my problem, the other construct wouldn't work for my access database unfortunately
jjb
+3  A: 

I want to know which rows in tableA don't have a match in tableB among the rows in tableB where fld4 is false.

Then you want to do this:

SELECT * 
FROM TableA
LEFT JOIN TableB on TableA.fld1 = TableB.fld2 AND TableB.fld4 = False
WHERE TableA.fld3 = True
    AND TableB.fld4 IS NULL
Joel Coehoorn
Will this work even though fld4 in a particular row in TableB is not actually null if you look into the "unjoined" tableB?
jjb
Yes, it will work because when SQL evaluates the LEFT OUTER JOIN it finds no match, which makes all of the TableB column NULL for that row in the results.
Tom H.
@jjb: The TableB.fld4 IS NULL is used to identify rows in TableA where a matching row in TableB could not be found, based on the join criteria. He could have written it as TableB.fld2 IS NULL, or with any other non-nullable field in TableB. Using one of the join fields is just considered best practice for this kind of query (so long as NULL = NULL is never true).
Peter
Thanks Guys I understand it a bit better now
jjb