0

I have a query with a joined subquery. If the subquery returns null, I want it to be ignored and I want to the rest of the query to work normally.

Currently I have something like:

SELECT a, b, c, d
FROM tblOne
JOIN tblTwo ON tblOne.a = tblTwo.a --this works fine
JOIN
    (SELECT a
    FROM tblThree) ON tblThree.a = tblOne.a

The problem is that if tblThree.a is null, the entire query returns null. So, I only want to use the subquery if tblThree.a is not null.

Can I do something with CASE or COALESCE, or some other way? Please give code examples.

3
  • 4
    do a left outer join to that subquery, if it didnt return anything it would be ignored Commented Sep 19, 2013 at 15:59
  • 1
    You aren't even selecting e or f -- why do you need that second join at all? Commented Sep 19, 2013 at 16:01
  • @mr.Reband That's just an example, not the full query. I'll edit the OP to avoid confusion. Commented Sep 19, 2013 at 16:05

4 Answers 4

6

Use a LEFT OUTER JOIN instead of an INNER JOIN. This will return all rows for the rest of the query, even if tblThree returns no matching rows. In this case the columns for tblThree will all be NULL.

Using your query (although I have added the required alias for the derived table):

SELECT a, b, c, d
FROM tblOne
INNER JOIN tblTwo ON tblOne.a = tblTwo.a
LEFT OUTER JOIN
(
    SELECT a, e, f
    FROM tblThree
) tblThree ON tblThree.a = tblOne.a

Note, as @491243 points out, the derived-table subquery here does not really make sense. You also most likely have an ambiguous column a in the SELECT clause. I'm guessing this is just an extrapolation of your real query though.

Sign up to request clarification or add additional context in comments.

2 Comments

actually you can eliminate the subquery since it does not contain any aggregation.
@491243 Agreed although this is most likely a simplification of the OP's real query. And you would probably (and most likely still do?) get column name collisions in the main SELECT clause.
1

Try changing your third join to a LEFT JOIN.

LEFT JOIN
    (SELECT a, e, f
    FROM tblThree) ON tblThree.a = tblOne.a

Then if a is null you will still get the original rows prior to the attempted join. Another option would be to add

WHERE a IS NOT NULL 

to your subquery to only return rows where a has a value.

Comments

0

I'm not sure what you mean by "if tblThree.a is null, the entire query returns null". A NULL value for a would affect one row, not all the results. Otherwise matching rows would still match.

The following might do what you want, though:

select a, b, c, d
from (SELECT a, b, c, d, count(tblThree.a) over () as nummatches, tblthree.a as t3a
      FROM tblOne JOIN
           tblTwo
           ON tblOne.a = tblTwo.a LEFT OUTER JOIN
           (SELECT a, e, f
            FROM tblThree
           ) tblThree
           ON tblThree.a = tblOne.a
    ) t
where nummatches = 0 or nummatches > 0 and t3a is not null;

This query counts the number of valid a values in tblThree. If there are none, then all are returned, otherwise only the matching ones are. By the way, you don't need the subquery for the table if you use table aliases with column names.

Comments

0

Try using EXISTS..

SELECT a, b, c, d
FROM tblOne, tblTwo
WHERE EXISTS(
SELECT a from tblThree
WHERE tblThree.a=tblOne.a) AND tblOne.a = tblTwo.a;

Dint verify this myself.. but, you got it, right?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.