tags:

views:

38

answers:

3

I'm trying to execute a query that looks similar to this:

SELECT <columns> FROM table1 
INNER JOIN table2 ON table1.id = table2.table1_id
INNER JOIN table3 ON table1.id = table3.table1_id
WHERE table3.column1 != 'foo' AND <other_conditions>
LIMIT 1;

The thing is--I want the query to return a result regardless of whether the record in table3 exists or not. That is--if the record in table3 is present, I want to check whether that record has a certain column value. If the record in table3 doesn't exist, I want the query to assume that the condition is TRUE.

Any pointers?

+1  A: 

You've come to a point where you noticed that there is a difference between WHERE conditions and JOIN conditions.

SELECT 
  <columns> 
FROM
  table1 
  INNER JOIN table2 ON table2.table1_id = table1.id
  LEFT  JOIN table3 ON table3.table1_id = table1.id AND table3.column1 <> 'foo' 
WHERE
  <other_conditions>
LIMIT 1;
Tomalak
Thanks. Your answer put me on the right track, but didn't take into account the fact that if `table3.column1` was `'foo'`, the query would return the result anyway.
vonconrad
@vonconrad: That's not the case. This joins against a sub-set of `table3` that does not even contain `column1 = 'foo'`. There is no way that these rows can show up in the result.
Tomalak
Sorry, I've tried it several times and it doesn't work. Because the `LEFT JOIN` conditions evaluate to false (the last one will be false, as `table3.column1 = 'foo'`), the `LEFT JOIN` will be excluded from the resultset as if there were no matching rows; the resultset will be complete. Now, this won't work for me as I *only* want a resultset if `table3.column1` isn't `'foo'` or the record in `table3` doesn't exist.
vonconrad
@vonconrad: Oh, I see. That's a misunderstanding on my end, you are of course correct.
Tomalak
A: 

You need to use an outer join to include table3 instead of an inner join.

Ruben
+2  A: 

You use a left join on the table. If no corresponding record exists, the value from the table will be null, so you can use coalesce to get a value that you can compare to the string:

SELECT <columns> FROM table1 
INNER JOIN table2 ON table1.id = table2.table1_id
LEFT JOIN table3 ON table1.id = table3.table1_id
WHERE COALESCE(table3.column1, '') != 'foo' AND <other_conditions>
LIMIT 1
Guffa
Perfect. The `COALESCE` was the final trigger. Thanks!
vonconrad