Skip to content

LeetCode 175: Combine Two Tables

A clear SQL guide for solving Combine Two Tables using LEFT JOIN.

Problem Restatement

We are given two tables: Person and Address.

The Person table stores each person’s ID, first name, and last name.

The Address table stores address records. Each address belongs to a person through personId.

We need to report this information for every person:

firstName, lastName, city, state

The important part is that every person must appear in the result, even if that person has no address.

If a person has no matching address row, city and state should be NULL.

Table Structure

Person table:

ColumnTypeMeaning
personIdintPrimary key for each person
lastNamevarcharPerson’s last name
firstNamevarcharPerson’s first name

Address table:

ColumnTypeMeaning
addressIdintPrimary key for each address
personIdintID of the person who owns this address
cityvarcharCity name
statevarcharState name

Example

Suppose Person contains:

personIdlastNamefirstName
1WangAllen
2AliceBob

And Address contains:

addressIdpersonIdcitystate
12New York CityNew York
23LeetcodeCalifornia

Person 2 has an address.

Person 1 does not have an address.

The result should be:

firstNamelastNamecitystate
AllenWangNULLNULL
BobAliceNew York CityNew York

Notice that the address with personId = 3 does not appear because there is no matching person in the Person table.

First Thought

We need data from both tables.

The names come from Person.

The city and state come from Address.

So we need a join between the two tables using personId.

The matching condition is:

Person.personId = Address.personId

But the problem asks for every person, even when there is no address.

That means an INNER JOIN is not enough, because INNER JOIN only keeps rows where both tables match.

We need LEFT JOIN.

Key Insight

Start from the Person table because every person must appear in the output.

Then attach address information when it exists.

This is exactly what LEFT JOIN does.

A LEFT JOIN keeps every row from the left table. If the right table has a matching row, SQL fills in the right table columns. If there is no match, SQL returns NULL for the right table columns.

Here, the left table should be Person.

The right table should be Address.

Algorithm

Use Person as the base table.

Join Address on the shared personId.

Select the four required columns:

Person.firstName
Person.lastName
Address.city
Address.state

Because this is a LEFT JOIN, all people remain in the result.

Correctness

The query begins from the Person table. Therefore, every row in Person is considered for the final result.

For each person, the join condition checks whether there is an address row with the same personId.

If such an address exists, the query returns that person’s firstName, lastName, city, and state.

If no address exists, the LEFT JOIN still keeps the person row. Since there is no matching row from Address, SQL fills city and state with NULL.

Therefore, the query returns exactly one report row for each person, with address data when available and NULL address fields when unavailable.

Complexity

Let P be the number of rows in Person.

Let A be the number of rows in Address.

MetricValueWhy
TimeDepends on the database engine and indexesThe database must join rows from Person and Address
SpaceDepends on the execution planThe database may use hash tables, indexes, or nested loops

In practice, with an index on Address.personId, the join can be efficient.

For LeetCode, the main point is choosing the correct join type.

Implementation

SELECT
    p.firstName,
    p.lastName,
    a.city,
    a.state
FROM Person AS p
LEFT JOIN Address AS a
    ON p.personId = a.personId;

Code Explanation

FROM Person AS p means we start with the Person table.

The alias p makes the query shorter and easier to read.

LEFT JOIN Address AS a

This attaches rows from the Address table when possible.

The alias a refers to the Address table.

ON p.personId = a.personId

This tells SQL how the two tables are related.

A person matches an address when both rows have the same personId.

The SELECT clause chooses the exact columns requested by the problem:

p.firstName,
p.lastName,
a.city,
a.state

If a person has no matching address, a.city and a.state become NULL.

Testing

Test with a person who has an address:

personIdlastNamefirstName
2AliceBob
addressIdpersonIdcitystate
12New York CityNew York

Expected output:

firstNamelastNamecitystate
BobAliceNew York CityNew York

Test with a person who has no address:

personIdlastNamefirstName
1WangAllen

No matching row exists in Address.

Expected output:

firstNamelastNamecitystate
AllenWangNULLNULL

Test with an address that has no matching person:

addressIdpersonIdcitystate
23LeetcodeCalifornia

If Person has no personId = 3, this row should not appear in the result.

That is why Person must be the left table.