DEV Community

Cristian Sifuentes
Cristian Sifuentes

Posted on

SQL Join Dark Arts: Anti Joins, Semi Joins, and Beyond

SQL Join Dark Arts

SQL Join Dark Arts: Anti Joins, Semi Joins, and Beyond

“Beyond INNER and OUTER lies the realm of the JOIN masters.”

Modern SQL isn’t just about fetching related rows—it’s about expressing logic concisely, filtering precisely, and maximizing performance.

In this article, we’ll explore the most underused join strategies in SQL, often called the “dark arts”:

  • Anti joins (NOT EXISTS, NOT IN, EXCEPT)
  • Semi joins (EXISTS, IN, INTERSECT)
  • Cartesian joins (CROSS JOIN)

We’ll walk through practical use cases and advanced examples that turn verbose logic into elegant queries.


Data Setup: Customers and Orders

CREATE TABLE Customers (
  id INT PRIMARY KEY,
  name TEXT
);

CREATE TABLE Orders (
  id INT PRIMARY KEY,
  customer_id INT REFERENCES Customers(id),
  total DECIMAL(10,2)
);
Enter fullscreen mode Exit fullscreen mode
INSERT INTO Customers VALUES
(1, 'Alice'), (2, 'Bob'), (3, 'Carol');

INSERT INTO Orders VALUES
(1, 1, 120.00), (2, 1, 80.00), (3, 2, 50.00);
Enter fullscreen mode Exit fullscreen mode

Semi Join with EXISTS

Use Case: Get customers who placed at least one order.

SELECT *
FROM Customers c
WHERE EXISTS (
  SELECT 1 FROM Orders o WHERE o.customer_id = c.id
);
Enter fullscreen mode Exit fullscreen mode

✅ Fast, short-circuiting filter. Equivalent with IN:

SELECT * FROM Customers
WHERE id IN (SELECT customer_id FROM Orders);
Enter fullscreen mode Exit fullscreen mode

Anti Join with NOT EXISTS

Use Case: Get customers who never placed an order.

SELECT *
FROM Customers c
WHERE NOT EXISTS (
  SELECT 1 FROM Orders o WHERE o.customer_id = c.id
);
Enter fullscreen mode Exit fullscreen mode

🚫 Avoid NOT IN if nulls exist:

-- Risky version
SELECT * FROM Customers
WHERE id NOT IN (SELECT customer_id FROM Orders);
Enter fullscreen mode Exit fullscreen mode

NOT EXISTS is null-safe and preferred for anti joins.


INTERSECT and EXCEPT

Set operations offer declarative alternatives.

-- Who placed orders? (like semi join)
SELECT id FROM Customers
INTERSECT
SELECT customer_id FROM Orders;

-- Who never placed orders? (like anti join)
SELECT id FROM Customers
EXCEPT
SELECT customer_id FROM Orders;
Enter fullscreen mode Exit fullscreen mode

✅ Cleaner for full-row matching, cross-database compatible (Postgres, SQL Server).


CROSS JOIN for Combinatorics

Use Case: Generate all combinations of colors and sizes.

CREATE TABLE Colors (name TEXT);
CREATE TABLE Sizes (name TEXT);

SELECT *
FROM Colors CROSS JOIN Sizes;
Enter fullscreen mode Exit fullscreen mode

Returns cartesian product of N × M rows.

✅ Useful for testing, generating permutations, or grid-like data.

🚨 Beware: No filter = explosion in row count.


Performance Tips

Pattern Use Case Caution
EXISTS Fast membership tests Great for subquery filters
IN Cleaner for small lists May degrade with large sets
NOT EXISTS Anti join with null safety Prefer over NOT IN
INTERSECT Clean set intersection Slower with large datasets
EXCEPT Anti set logic Can replace outer joins
CROSS JOIN Full combination logic Limit with WHERE clause

Bonus Challenge

Try these exercises to reinforce your skills:

  • Get products not ordered in the last 30 days (anti join)
  • Find users who posted both articles and comments (intersect)
  • Generate color-size combos for a product grid (cross join)

Final Thoughts: Beyond Joins, Into Logic

Advanced join patterns help you:

  • Write faster SQL
  • Express intent clearly
  • Avoid imperatively nested logic

“Your SQL should not only fetch rows, it should tell a story.”

#SQL #Joins #SemiJoin #AntiJoin #CrossJoin #EXCEPT #INTERSECT #DataEngineering #AdvancedSQL

Top comments (0)