The aliases are the entire trick: s and m are the same rows wearing different roles, and every column reference must pick a costume — unaliased columns are ambiguity errors at best, silent wrong-role picks at worst. Three standard uses: hierarchy hops (one level per join — unknown depth graduates to recursive_cte), row-pairings (join on the common column, s.id < s2.id to avoid self- and mirror-pairs), and offset comparisons.
SELECT s.name, m.name AS mentor FROM staff s JOIN staff m ON m.id = s.mentor_id ORDER BY s.name;
SELECT s.name, m.name AS mentor FROM staff s LEFT JOIN staff m ON m.id = s.mentor_id ORDER BY s.name;
The INNER self-join dropped Io, the root contributor with no mentor — a table joined to itself needs LEFT to keep the roots, and the two aliases are the whole trick.
Meaningful aliases (emp/mgr, not a/b); LEFT when roots must survive; the < trick on pairings.