Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL left outer join with where clause - return unmatched rows

I have two tables: pq and pe. I am trying to LEFT OUTER JOIN left table (pq) on right table (pe).

  • pq has primary key column id
  • pe has two-column primary key, so it may have many pqid's or none
  • pe.uid column has to be used to extract only relevant data (WHERE pe.uid = "12345")
  • pe.data should be joined to every pq.id row

Here is how tables look:

pq:
id | data
1  | "abc"
2  | "efg"

pe:
pqid | uid   | data
2    | 54321 | "uvw"
2    | 12345 | "xyz"

I can use the following query to match first 2 rows of pq.id to pe.pqid

SELECT pq.id, pq.data, pe.data FROM pq
    LEFT OUTER JOIN pe ON pq.id = pe.pqid
    ORDER BY pq.id LIMIT 2

I get:

pq.id | pq.data |  pe.data
1     | "abc"   |  
2     | "efg"   |  "uvw"

But if I use the WHERE statement like this:

SELECT pq.id, pq.data, pe.data FROM pq
    LEFT OUTER JOIN pe ON pq.id = pe.pqid
    WHERE pe.uid='12345'
    ORDER BY pq.id LIMIT 2

I only get one row with matching pe.pqid AND pe.uid:

pq.id | pq.data |  pe.data
2     | "efg"   |  "xyz"

So with the WHERE clause I get the right pe.data, but I don't get pq rows that have no pq.id matching pe.pqid

I need to get this:

pq.id | pq.data |  pe.data
1     | "abc"   |  
2     | "efg"   |  "xyz"
like image 871
Xeos Avatar asked Jul 28 '13 17:07

Xeos


People also ask

Does outer join result include non-matching rows?

In SQL Full Outer Join, all rows from both the tables are included. If there are any unmatched rows, it shows NULL values for them.

What happens to unmatched rows with the full outer join operator?

When performing an inner join, rows from either table that are unmatched in the other table are not returned. In an outer join, unmatched rows in one or both tables can be returned.

How do you return unmatched rows in SQL?

You can use LEFT OUTER JOIN to return unmatched tuples from the table mentioned on its left, RIGHT for the table mentioned on its RIGHT, or FULL to get both. Note that the word “OUTER” is optional and assumed in most DBMS if you specify LEFT, RIGHT, or FULL.


1 Answers

Yes. The where clause is turning the left outer join into an inner join.

Why? The value of pe.pqid is NULL (as is pe.uid) when there is no match. So the comparison in the where clause fails (almost all comparisons to NULL return NULL which is considered false).

The solution is to move the comparison to the on clause:

SELECT pq.id, pq.data, pe.data
FROM pq LEFT OUTER JOIN
     pe
     ON pq.id = pe.pqid and
        pe.uid='12345'
ORDER BY pq.id LIMIT 2
like image 173
Gordon Linoff Avatar answered Oct 17 '22 13:10

Gordon Linoff