Free tutorials & notes in Hindi & English · Clean code examples · Mobile friendly learning
MySQL + SQL · Lesson 70

CROSS JOIN and SELF JOIN

CROSS JOIN Means Every Combination

CROSS JOIN has no matching predicate: each row from one input is paired with every row from the other. Its row-count formula is exact—M × N. This makes it useful for generating a designed grid and risky on large or accidental inputs.

CREATE TABLE exam_shifts (
  shift_name VARCHAR(20) PRIMARY KEY
);
INSERT INTO exam_shifts VALUES ('Morning'), ('Afternoon');
Three classes × two shifts must produce six rows. Predict this before executing.

Verified Class–Shift Schedule

SELECT c.class_name, e.shift_name
FROM classes AS c
CROSS JOIN exam_shifts AS e
ORDER BY c.class_id, e.shift_name;
X-A | Afternoon X-A | Morning X-B | Afternoon X-B | Morning XI-A | Afternoon XI-A | Morning

The alphabetical shift order places Afternoon before Morning. If the business order must be Morning then Afternoon, store a numeric shift_order column and sort by it.

Avoid Accidental Cartesian Products

-- Intent is unclear and row count multiplies:
SELECT s.student_name, c.class_name
FROM join_students AS s
CROSS JOIN classes AS c;

Five students × three classes returns 15 rows, most of which assert no real relationship. A comma-separated FROM list without a connecting predicate can create the same problem. Use explicit JOIN syntax, review the ON clause and estimate output size.

Production guard: A CROSS JOIN of 100,000 and 50,000 rows has five billion combinations before later filtering. Restrict inputs first and confirm that the grid is required.

SELF JOIN Means Two Roles for One Table

SELF JOIN is a pattern, not a special keyword. The table appears twice under aliases. Each alias represents a role, such as first student and second student.

SELECT s1.student_name AS student_1,
       s2.student_name AS student_2,
       s1.class_id
FROM join_students AS s1
JOIN join_students AS s2
  ON s2.class_id = s1.class_id
 AND s1.student_id < s2.student_id
ORDER BY s1.student_id, s2.student_id;

Verified Same-Class Pairs

Aarav | Meera | 10 Kabir | Sana | 20

The equality condition requires the same non-NULL class. The strict less-than condition does two jobs: it removes Aarav–Aarav self-pairs and prevents both Aarav–Meera and Meera–Aarav from appearing. Vihaan has no class, so NULL equality does not match.

ConditionEffect
s1.id = s2.idOnly the same row
s1.id != s2.idBoth directions remain
s1.id < s2.idOne direction, no self-pair

Other Useful SELF JOIN Patterns

Hierarchy

SELECT e.employee_name,
       m.employee_name AS manager_name
FROM employees AS e
LEFT JOIN employees AS m
  ON m.employee_id = e.manager_id;

LEFT JOIN preserves top-level employees whose manager_id is NULL. Other patterns include consecutive events, comparing versions, finding overlapping ranges and matching rows that share an attribute. Each requires a condition that prevents meaningless pairs.

Performance and Practice

  • Index self-referencing keys such as manager_id and equality attributes such as class_id.
  • Estimate pair counts; a group of N rows can create N(N−1)/2 unique unordered pairs.
  • Filter each role as early as the requirement safely allows.
  • Use EXPLAIN, but first verify that pair-generation logic is correct.

Practice: add an Evening shift and predict nine combinations; create three students in one class and predict three unique pairs; write a manager SELF JOIN that still displays the principal with no manager.

Official References

Syntax and optimizer notes were checked against the official MySQL 8.4 manual. Always test plans and row counts on your own schema and data.

Frequently Asked Questions

What does CROSS JOIN return?
It returns every combination of a row from the first input and a row from the second. For M and N rows, the result has M × N rows.
Is CROSS JOIN always a mistake?
No. It is correct for intentional combinations such as every class with every exam shift. It is dangerous when produced by a missing relationship predicate.
What is a SELF JOIN?
It is a normal join in which the same table appears under two aliases so different rows—or roles—can be compared.
How can I prevent mirrored self-join pairs?
Use a strict ordering predicate such as s1.student_id < s2.student_id. It excludes self-pairs and keeps only one direction of each pair.
Does SELF JOIN require a special keyword?
No. Use the table twice with distinct aliases and choose INNER or OUTER join semantics according to the requirement.
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.