-- -- JOIN -- Test join clauses -- CREATE TABLE J1_TBL ( i integer, j integer, t text ); CREATE TABLE J2_TBL ( i integer, k integer ); CREATE TABLE JOIN3_TBL ( i integer, j integer, y integer ); CREATE TABLE JOIN4_TBL ( k integer, z integer ); INSERT INTO J1_TBL VALUES (1, 3, 'one'); INSERT INTO J1_TBL VALUES (2, 2, 'two'); INSERT INTO J1_TBL VALUES (3, 1, 'three'); INSERT INTO J1_TBL VALUES (4, 0, 'four'); INSERT INTO J2_TBL VALUES (1, -1); INSERT INTO J2_TBL VALUES (2, 2); INSERT INTO J2_TBL VALUES (3, -3); INSERT INTO J2_TBL VALUES (2, 4); -- -- CORRELATION NAMES -- Make sure that table/column aliases are supported -- before diving into more complex join syntax. -- SELECT '' AS "xxx", * FROM J1_TBL AS tx; SELECT '' AS "xxx", * FROM J1_TBL tx; SELECT '' AS "xxx", * FROM J1_TBL AS t1 (a, b, c); SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b, c); SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e); SELECT '' AS "xxx", t1.a, t2.e FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e) WHERE t1.a = t2.d; -- -- CROSS JOIN -- Qualifications are not allowed on cross joins, -- which degenerate into a standard unqualified inner join. -- SELECT '' AS "xxx", * FROM J1_TBL CROSS JOIN J2_TBL; -- ambiguous column SELECT '' AS "xxx", i, k, t FROM J1_TBL CROSS JOIN J2_TBL; -- resolve previous ambiguity by specifying the table name SELECT '' AS "xxx", t1.i, k, t FROM J1_TBL t1 CROSS JOIN J2_TBL t2; SELECT '' AS "xxx", ii, tt, kk FROM (J1_TBL CROSS JOIN J2_TBL) AS tx (ii, jj, tt, ii2, kk); SELECT '' AS "xxx", tx.ii, tx.jj, tx.kk FROM (J1_TBL t1 (a, b, c) CROSS JOIN J2_TBL t2 (d, e)) AS tx (ii, jj, tt, ii2, kk); -- -- -- Inner joins (equi-joins) -- -- -- -- Inner joins (equi-joins) with USING clause -- The USING syntax changes the shape of the resulting table -- by including a column in the USING clause only once in the result. -- -- Inner equi-join on specified column SELECT '' AS "xxx", * FROM J1_TBL INNER JOIN J2_TBL USING (i); -- Same as above, slightly different syntax SELECT '' AS "xxx", * FROM J1_TBL JOIN J2_TBL USING (i); SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, d) USING (a); SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, b) USING (b); -- -- NATURAL JOIN -- Inner equi-join on all columns with the same name -- SELECT '' AS "xxx", * FROM J1_TBL NATURAL JOIN J2_TBL; SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); -- mismatch number of columns -- currently, Postgres will fill in with underlying names SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); -- -- Inner joins (equi-joins) -- SELECT '' AS "xxx", * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); SELECT '' AS "xxx", * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); SELECT '' AS "xxx", * FROM J1_TBL CROSS JOIN J2_TBL; -- -- Non-equi-joins -- SELECT '' AS "xxx", * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k); -- -- Outer joins -- SELECT '' AS "xxx", * FROM J1_TBL OUTER JOIN J2_TBL USING (i); SELECT '' AS "xxx", * FROM J1_TBL LEFT OUTER JOIN J2_TBL USING (i); SELECT '' AS "xxx", * FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); SELECT '' AS "xxx", * FROM J1_TBL FULL OUTER JOIN J2_TBL USING (i); -- -- More complicated constructs -- -- -- Clean up -- DROP TABLE J1_TBL; DROP TABLE J2_TBL;