Exploring the Versatility of the ON Clause in SQL Joins

assorted candies in plastic containers
Photo by JACQUELINE BRANDWAYN / Unsplash

The ON clause in SQL plays a pivotal role in defining how two tables relate to each other when performing a join operation. While many think of ON as limited to equality conditions (e.g., table1.id = table2.id), it’s far more versatile. This blog post explores the various ways you can use the ON clause to handle more complex relationships, perform filtering, and even create mappings that go beyond simple equality.


What Does the ON Clause Do?

The ON clause specifies the relationship, or mapping, between the table in the FROM statement and the table being joined. This relationship is written as a conditional statement. For example:

SELECT products.product_name, suppliers.supplier_name
FROM products
LEFT JOIN suppliers
ON products.supplier_id = suppliers.id;

Here, the relationship is defined by matching products.supplier_id with suppliers.id.

But that’s just the beginning! Let’s explore the flexibility of the ON clause with a variety of examples.


1. Beyond Equality: Using Other Operators

While equality (=) is the most common condition in ON clauses, you can use any valid boolean condition. For example:

Greater Than, Less Than: You can use comparison operators to define more dynamic relationships:

SELECT orders.order_id, customers.name
FROM orders
JOIN customers
ON orders.customer_id = customers.id AND orders.total_amount > 100;

This example not only matches orders.customer_id with customers.id, but also filters the join to include only orders above a certain threshold.

Date Difference: Suppose you have a table of weather records, and you want to join rows where one record’s date is exactly one day after the other.

SELECT w1.id, w1.recordDate, w2.recordDate
FROM Weather w1
JOIN Weather w2
ON DATEDIFF(w1.recordDate, w2.recordDate) = 1;

2. Pre-Filtering with the ON Clause

Typically, filtering is handled in the WHERE clause after the tables have been joined. However, the ON clause can also be used to filter one or both tables before the join happens.

Combining Conditions: You can chain multiple conditions to fine-tune the rows being joined:

SELECT employees.name, departments.name
FROM employees
JOIN departments
ON employees.department_id = departments.id
   AND employees.hire_date >= '2020-01-01';

Filtering Specific Records: Imagine you only want to include acquisitions where the acquired company is not a specific one:

SELECT products.product_name, suppliers.supplier_name
FROM products
LEFT JOIN suppliers
ON products.supplier_id = suppliers.id
   AND suppliers.id != 1000;

In this case, the ON clause ensures that records with a supplier_id of 1000 are excluded before the join is executed.


3. Joining on Calculated Fields

You can also create dynamic mappings by joining on calculated fields or derived values:

Using Math Functions:

SELECT transactions.id, discounts.id
FROM transactions
JOIN discounts
ON transactions.amount % discounts.min_amount = 0;

Using String Functions:

SELECT users.username, logs.action
FROM users
JOIN logs
ON LOWER(users.username) = LOWER(logs.user_identifier);

This approach allows you to create mappings that are based on more than just the raw data in your tables.


4. The ON Clause as a Localized WHERE

You can think of the ON clause as a localized WHERE clause that applies only to the tables being joined. This means you can filter data from one or both tables in a way that doesn’t affect the rest of your query. For example:

SELECT employees.name, projects.title
FROM employees
JOIN projects
ON employees.project_id = projects.id
   AND projects.status = 'active';

Here, the ON clause ensures that only active projects are considered in the join, without filtering out other rows from the employees table.


5. Self-Joins with Custom Conditions

The ON clause is especially powerful in self-joins, where a table is joined with itself. This is useful for finding relationships between rows in the same table:

Consecutive Days:

SELECT w1.id, w2.id
FROM Weather w1
JOIN Weather w2
ON DATEDIFF(w1.recordDate, w2.recordDate) = 1
WHERE w1.temperature > w2.temperature;

This query compares weather records for consecutive days and identifies cases where the temperature increased.


6. Combining ON and USING

While the USING keyword is a shorthand for equality joins on columns with the same name, the ON clause gives you full control for more complex mappings. Use ON when:

  • Columns don’t share the same name.
  • You need to define a relationship beyond equality.
  • Additional filtering is required as part of the join logic.

For example:

SELECT orders.id, customers.name
FROM orders
LEFT JOIN customers
ON orders.customer_id = customers.id
   AND orders.status = 'completed';

Key Takeaways

  • The ON clause is not limited to equality conditions (=); it can use any boolean condition like >, <, DATEDIFF, or even complex expressions.
  • Use the ON clause to filter rows before joining, saving resources and improving performance.
  • The ON clause acts like a scoped WHERE clause for join-specific logic.
  • Self-joins and calculated joins unlock powerful ways to analyze relationships within the same table.

By mastering the ON clause, you can write more flexible, efficient, and insightful SQL queries. So go ahead—experiment with different conditions and take your SQL skills to the next level!

Author:
Yoan Caboste
Powered by The Information Lab
1st Floor, 25 Watling Street, London, EC4M 9BR
Subscribe
to our Newsletter
Get the lastest news about The Data School and application tips
Subscribe now
© 2025 The Information Lab