Databases 6 min read

Why LEFT JOIN Still Returns All Left Rows: ON vs WHERE Explained

This article explains why a LEFT JOIN always returns all rows from the left table, clarifies the difference between ON and WHERE clauses, demonstrates the behavior with multiple SQL examples and code snippets, and highlights the special handling of LEFT/RIGHT/FULL joins versus inner joins.

macrozheng
macrozheng
macrozheng
Why LEFT JOIN Still Returns All Left Rows: ON vs WHERE Explained

When writing SQL, I tried to use

A LEFT JOIN B ON ... AND ...

to merge two rows into one, but still got two rows.

I later discovered that the

AND

after

ON

does not filter the result count; it only determines whether rows from table B are shown, while rows from table A are always returned.

Regardless of whether the condition after

AND

is

A.id = 1

or

B.id = 1

, all records from table A appear, with matching B records (or nulls) for the specified condition.

Example SQL:

<code>SELECT *
FROM student s
LEFT JOIN class c ON s.classId = c.id
ORDER BY s.id</code>

Adding an

AND

condition to the

ON

clause:

<code>SELECT *
FROM student s
LEFT JOIN class c ON s.classId = c.id AND s.name = '张三'
ORDER BY s.id</code>

Using

ON

versus

WHERE

in a LEFT JOIN:

The ON condition is applied while generating the temporary table; it does not remove rows from the left table, even if the condition is false.

The WHERE condition filters the temporary table after it is created, so rows that do not satisfy the condition are removed entirely.

Assume two tables:

Table 1:

Table 2:

Two SQL queries:

<code>SELECT * FROM tab1 LEFT JOIN tab2 ON (tab1.size = tab2.size) WHERE tab2.name='AAA'</code>
<code>SELECT * FROM tab1 LEFT JOIN tab2 ON (tab1.size = tab2.size AND tab2.name='AAA')</code>

Process of the first query:

Intermediate table uses

ON

condition:

tab1.size = tab2.size

.

After the temporary table is created, the

WHERE

clause filters rows where

tab2.name='AAA'

.

Process of the second query:

Intermediate table uses combined

ON

condition:

tab1.size = tab2.size AND tab2.name='AAA'

.

Note: Even if the condition is false, LEFT JOIN still returns rows from the left table.

The special nature of

LEFT JOIN

,

RIGHT JOIN

, and

FULL JOIN

is that they always return rows from the respective side(s) regardless of the

ON

condition, whereas

INNER JOIN

does not have this behavior; placing the condition in

ON

or

WHERE

yields the same result set.

SQLDatabaseLEFT JOINWHERE clauseON clause
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.