CROSS Joins in PostgreSQL: How to Join Two Tables Without a Common Column

Updated: January 5, 2024 By: Guest Contributor Post a comment

Introduction

CROSS joins, also known as Cartesian products, are used in SQL to combine rows from two or more tables without the requirement of a common column. These joins can be invaluable when needing to enumerate all possible combinations between datasets.

Understanding CROSS Joins

A CROSS join in PostgreSQL pairs each row from one table with all rows in another table. This type of join does not necessitate a join condition. Instead, it creates a Cartesian product, where the result set has a number of rows equal to the product of the number of rows in the two joined tables.

SELECT *
FROM table1
CROSS JOIN table2;

This is the simplest form of a cross join query. When executed, it produces a combination of each row from table1 with every row of table2.

Practical Examples

Basic Example

CREATE TABLE colors (
    color_id SERIAL PRIMARY KEY,
    color_name VARCHAR NOT NULL
);

CREATE TABLE shades (
    shade_id SERIAL PRIMARY KEY,
    shade_name VARCHAR NOT NULL
);

INSERT INTO colors (color_name)
VALUES 
    ('Red'),
    ('Blue');

INSERT INTO shades (shade_name)
VALUES 
    ('Dark'),
    ('Light');

SELECT *
FROM colors
CROSS JOIN shades;

In this basic example, we create and populate two tables and then perform a CROSS join. The result will enumerate every possible combination of color_name and shade_name.

Using CROSS JOIN with WHERE Clause

Sometimes, results from a CROSS join need to be filtered. This is where a WHERE clause comes into play.

SELECT *
FROM colors
CROSS JOIN shades
WHERE colors.color_name = 'Red';

While the CROSS join doesn’t require a condition to join, here we’re using a WHERE clause to filter only those combinations that include the color ‘Red’.

Joining More Than Two Tables

CROSS joins are not limited to just two tables. You can join multiple tables to generate a larger set of combinations.

CREATE TABLE textures (
    texture_id SERIAL PRIMARY KEY,
    texture_name VARCHAR NOT NULL
);

INSERT INTO textures (texture_name)
VALUES 
    ('Glossy'),
    ('Matte');

SELECT *
FROM colors
CROSS JOIN shades
CROSS JOIN textures;

After creating a third table, we use multiple CROSS joins to combine data from all three tables. This example showcases a three-dimensional Cartesian product.

Creating Synthetic Data

CROSS joins can be utilized to generate synthetic data for testing purposes.

SELECT
    'Pattern ' || colors.color_name || ' ' || shades.shade_name AS pattern_description,
    round(random() * 100)::int AS pattern_score
FROM generate_series(1, 5) as sequences(sequence_id)
CROSS JOIN colors
CROSS JOIN shades
LIMIT 10;

Here, we use a sequence generator with CROSS joins to create a set of pattern descriptions and random pattern scores. This is great for scenarios where we need a set of sample data to work with.

Advanced Techniques

Combining CROSS and INNER Joins

While CROSS joins are great for pairing rows without a common column, combining them with INNER joins allows for greater flexibility in your queries when there are relations between some tables.

SELECT *
FROM colors
CROSS JOIN shades
INNER JOIN textures ON textures.texture_name = 'Glossy';

This combines the Cartesian product of colors and shades with an INNER join on the textures table where the texture name is ‘Glossy’.

Using CROSS Joins with Aggregate Functions

Aggregations can be performed on the result sets of CROSS joins to discern valuable insights or summaries.

SELECT colors.color_name, COUNT(*) AS count_combinations
FROM colors
CROSS JOIN shades
GROUP BY colors.color_name;

By utilizing a GROUP BY clause with a count, we count the number of combinations for each color.

When To Use a CROSS Join

CROSS joins should be used when you need to:

  • Create all possible combinations between rows of two or more tables.
  • Generate synthetic datasets for testing purposes.
  • Perform complex calculations that depend on the Cartesian product of multiple tables.

Considerations

It’s important to be cautious with CROSS joins as they can lead to a massive number of rows in the result set, which can be overhead for the database and application.

Conclusion

In this tutorial, we’ve explored the utility of CROSS joins in PostgreSQL through various examples, illustrating how to join tables without a common column, as well as combining them with other SQL constructs for more complex queries. Remember, while powerful, CROSS joins should be used judiciously to avoid unwieldy results sets.