-- http://en.wikipedia.org/wiki/Join_(sql) SET client_encoding TO 'latin-1'; -- Inner join, with the old SQL syntax SELECT name, title FROM Books, Authors WHERE Books.author = Authors.id; -- Does not display books without an author -- This inner join is also an equi-join (equality sign in WHERE) -- Inner join, new syntax. Apart from the syntax, same as above SELECT name, title FROM Books INNER JOIN Authors ON Books.author = Authors.id; -- If the fields had the same name, we could have used USING -- Cross join. Uninteresting but funny. -- SELECT * FROM Books CROSS JOIN Authors; -- Left outer join. There is no "old syntax" here. SELECT name, title FROM Books LEFT OUTER JOIN Authors ON Books.author = Authors.id; -- LEFT means we retain tuples from the left table (Books) even when they do -- not match (books without an author) -- If we don't like the empty name column: SELECT CASE WHEN name IS NULL THEN 'Unknown author' ELSE name END, title FROM Books LEFT OUTER JOIN Authors ON Books.author = Authors.id; -- Right outer join SELECT name, title FROM Books RIGHT OUTER JOIN Authors ON Books.author = Authors.id; -- RIGHT means we retain tuples from the right table (Authors) even when they do -- not match (people who did not write a book) -- A right outer join can always be replaced by a left one by swapping -- the tables. This join is the same as the previous one. SELECT name, title FROM Authors LEFT OUTER JOIN Books ON Books.author = Authors.id; -- Full outer join, retain non-matching tuples from both sides SELECT name, title FROM Books FULL OUTER JOIN Authors ON Books.author = Authors.id; -- TODO: use subqueries instead of outer joins, play with self-joins, etc