RadhaPublication
HomeInterviewLearning PathsRole TracksMockBooksPricing
Login / Sign UpLog in

© 2026 Radha Publication. All rights reserved.

Shop on AmazonDonateContactPrivacyTerms
SQL questions
TrickySQL#456 min readJul 11, 2026

CROSS JOIN

practice
learning
Practice modeTest yourself instead of reading straight through

Interviewers love CROSS JOIN because one tiny keyword can quietly turn two small tables into a huge result set.

Question: What does CROSS JOIN do in SQL?

Answer: A CROSS JOIN returns every possible pair of rows between two tables. If the first table has 3 rows and the second has 4 rows, the result has 12 rows. It does not match rows by a key; it simply combines everything with everything.

Interview-Ready Answer: I use CROSS JOIN when I want a Cartesian product, meaning every row from table A is paired with every row from table B. So if I have 10 rows and 20 rows, I should expect 200 output rows. I would choose it intentionally for things like generating combinations, but I would avoid it in normal joins because it can blow up row counts very quickly.

🧠 Memory Map
Memory map — visual summary of this topic

What it is

CROSS JOIN is the SQL way to say Cartesian product. A Cartesian product means every row on the left is combined with every row on the right. There is no matching condition, no ON clause, and no filtering by key.

  1. The database reads the first input table.
  2. For each row in that table, it visits all rows in the second table.
  3. It outputs one combined row for each pairing.
  4. It repeats until all pairings are produced.

If table A has m rows and table B has n rows, the output has m × n rows. That is the mental model to remember under pressure.

When and why to use it

  • Generating all combinations, like colors × sizes or dates × stores.
  • Building test data or report grids where every category needs a slot.
  • Applying a single constant row to many rows, such as pairing each user with a parameter set.

Because it multiplies rows, use it only when the multiplication is the point. If you are trying to match records by customer id or order id, you want an INNER JOIN or LEFT JOIN, not a cross join.

Comparison with related joins

Join typeWhat it doesOutput size
CROSS JOINAll pairsm × n
INNER JOINMatches by conditionOnly matching rows
LEFT JOINAll left rows plus matchesAt least left size
Comma FROM listOld-style cross joinm × n

In many databases, FROM a, b is equivalent to FROM a CROSS JOIN b, but the explicit keyword is safer because it makes intent obvious. Interviewers like that distinction because it shows you understand both syntax and risk.

Performance and edge cases

Time complexity is effectively O(m × n) because the engine must produce every pair. The main cost is not just CPU; it is the sheer number of rows that may need memory, sorting, network transfer, or disk spill. A 1,000-row table crossed with another 1,000-row table makes 1,000,000 rows; 10,000 by 10,000 makes 100,000,000 rows, which is often too big for an interactive query.

  • If either side is empty, the result is empty.
  • Duplicates are preserved, so repeated rows multiply too.
  • Leaving out a join predicate in a regular join can accidentally behave like a cross join and cause a row explosion.

Memory rule: think pairing engine, not matching engine. If you need to match, cross join is the wrong tool. If you need every combination, it is exactly the right tool.

Real-world story

Imagine a checkout service in an e-commerce app that needs to show every shipping option for every package type in a cart. The product team wants a grid like standard, express, and pickup for each package size. A clean CROSS JOIN can generate those combinations from two small lookup tables.

Now for the bug story: an engineer meant to join orders to customers by customer_id, but accidentally wrote a cross join. The query returned millions of rows instead of thousands, the API timed out, and the database CPU spiked. In logs, you would see huge result sets, slow sorts, and maybe temp-file spill messages; users would see duplicate options, slow page loads, or a spinner that never finishes.

The lesson is simple: CROSS JOIN is powerful when you want combinations, but dangerous when you really wanted matching. In production, that difference can be the gap between a neat pricing grid and an outage.

SQL
-- Example 1: intentional CROSS JOIN to build every color-size combination.
WITH colors(color) AS (
  VALUES ('Red'), ('Green'), ('Blue')
),
sizes(size) AS (
  VALUES ('S'), ('M')
)
SELECT
  c.color,
  s.size
FROM colors AS c
CROSS JOIN sizes AS s
ORDER BY c.color, s.size;

-- Example 2: edge case. If one input is empty, the result is empty too.
WITH colors(color) AS (
  VALUES ('Red'), ('Green')
),
empty_discounts(discount) AS (
  SELECT '10%'
  WHERE 1 = 0
)
SELECT
  c.color,
  d.discount
FROM colors AS c
CROSS JOIN empty_discounts AS d;

Follow-up & Tricky Questions:

  • When would you use CROSS JOIN on purpose? When you need every combination, such as generating a matrix of dates, colors, sizes, or test cases.
  • Is FROM a, b the same as CROSS JOIN? In most SQL engines, yes in effect: it produces the Cartesian product. The explicit CROSS JOIN is clearer and less error-prone.
  • How do you stop a row explosion? Add the correct join predicate, filter early, or pre-aggregate one side so you do not multiply unnecessary rows.
  • Does CROSS JOIN keep unmatched rows? No. That is what outer joins do. A cross join keeps all combinations, which is a different idea entirely.
  • What happens if one input table is empty? The result is empty, because there are no pairs to emit.
  • Can you use ON with CROSS JOIN? No in standard SQL; if you need conditions, use a regular join or put the filter in WHERE after the cross product, knowing that it still starts from all pairs.
  • Tricky: does a cross join remove duplicates? No. Duplicate input rows produce duplicate combinations, often many more than candidates expect.
  • Tricky: is a cross join always bad? No. It is very useful when the goal is combinations, but dangerous when used by accident or on large tables.
  • Tricky: what is the biggest practical risk? The output can become enormous very quickly, causing slow queries, memory pressure, temp-file spills, and timeouts.

Common Mistakes:

  • Forgetting the join condition. Correction: if you meant to match rows, use INNER JOIN or LEFT JOIN with the right ON clause.
  • Using CROSS JOIN on large tables. Correction: estimate the output first; if the product is huge, pre-filter or rethink the query.
  • Assuming it behaves like an outer join. Correction: it does not preserve unmatched rows; it simply pairs everything.
  • Thinking duplicates disappear. Correction: duplicates multiply, so repeated rows can dramatically increase the result set.

Memory Hook: Think of a wardrobe: every shirt gets tried with every pair of pants. If you have 3 shirts and 4 pants, you get 12 outfits. That is CROSS JOIN.

Cheat Sheet:

  • CROSS JOIN = Cartesian product.
  • Row count = left rows × right rows.
  • No ON match condition.
  • Great for combinations, dangerous by accident.
  • Empty input on either side means empty output.

Practice Tasks:

  • Write a query that generates all combinations of 3 product colors and 2 sizes.
  • Take two small tables and predict the exact number of rows before running a CROSS JOIN.
  • Rewrite an accidental cross join into a proper INNER JOIN using a matching key.
Previous
Back to Questions←→to navigate
Next

Recommended Resources

Recommended Book

Cracking the Coding Interview

189 Programming Questions and Solutions

Recommended Book

Cracking the Coding Interview

189 Programming Questions and Solutions

-- Example 1: intentional CROSS JOIN to build every color-size combination. WITH colors(color) AS ( VALUES ('Red'), ('Green'), ('Blue') ), sizes(size) AS ( VALUES ('S'), ('M') ) SELECT c.color, s.size FROM colors AS c CROSS JOIN sizes AS s ORDER BY c.color, s.size; -- Example 2: edge case. If one input is empty, the result is empty too. WITH colors(color) AS ( VALUES ('Red'), ('Green') ), empty_discounts(discount) AS ( SELECT '10%' WHERE 1 = 0 ) SELECT c.color, d.discount FROM colors AS c CROSS JOIN empty_discounts AS d;