CREATE TABLE test (a INTEGER, b INTEGER);INSERT INTO test VALUES (11, 1), (12, 2), (13, 3);CREATE TABLE test2 (b INTEGER, c INTEGER);INSERT INTO test2 VALUES (1, 10), (1, 20), (2, 30);SELECT a, test.b, c FROM test INNER JOIN test2 ON test.b = test2.bORDER BY c;
LEFT OUTER JOIN returns all rows from the left table and matched rows from the right table. When no match exists, NULL values are used for right table columns.
CREATE TABLE integers(i INTEGER, j INTEGER);INSERT INTO integers VALUES (1, 2), (2, 3), (3, 4);CREATE TABLE integers2(k INTEGER, l INTEGER);INSERT INTO integers2 VALUES (1, 10), (2, 20);SELECT *FROM integers LEFT OUTER JOIN integers2 ON integers.i = integers2.kORDER BY i;
-- Filters out NULL rows (equivalent to INNER JOIN)SELECT *FROM integers LEFT OUTER JOIN integers2 ON integers.i = integers2.kWHERE k IS NOT NULLORDER BY i;-- Returns: (1,2,1,10), (2,3,2,20)
Conditions in the ON clause are evaluated before the LEFT JOIN generates NULL values. Conditions in WHERE are evaluated after, which can filter out the NULL rows.
-- Range joinSELECT *FROM integers LEFT OUTER JOIN integers2 ON integers.i < integers2.kWHERE integers.i <= 2ORDER BY i;-- Multiple conditionsSELECT *FROM integers LEFT OUTER JOIN integers2 ON integers.i < integers2.k AND integers.i < integers2.lWHERE integers.i <= 2ORDER BY i;-- Expression-based joinSELECT *FROM integers LEFT OUTER JOIN integers2 ON i + l = 21ORDER BY i;
FULL OUTER JOIN returns all rows from both tables, with NULL values where matches don’t exist.
CREATE TABLE integers(i INTEGER, j INTEGER);INSERT INTO integers VALUES (1, 1), (3, 3);CREATE TABLE integers2(k INTEGER, l INTEGER);INSERT INTO integers2 VALUES (1, 10), (2, 20);SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i = integers2.kORDER BY i;
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i = integers2.k AND integers.j > integers2.lORDER BY i, j, k, l;-- Returns rows from both tables as NULL matches-- when the additional predicate fails
-- Find employees and their managersSELECT e1.empno AS employee, e2.empno AS managerFROM empsalary e1INNER JOIN empsalary e2 ON e1.manager_id = e2.empno;-- Find pairs of employees in the same departmentSELECT e1.empno AS emp1, e2.empno AS emp2, e1.depnameFROM empsalary e1INNER JOIN empsalary e2 ON e1.depname = e2.depname AND e1.empno < e2.empno;
-- Find rows in left table with no match in rightSELECT *FROM integers LEFT JOIN integers2 ON integers.i = integers2.kWHERE integers2.k IS NULL;-- Alternative: NOT INSELECT *FROM integers WHERE i NOT IN (SELECT k FROM integers2);-- Alternative: NOT EXISTSSELECT *FROM integers iWHERE NOT EXISTS ( SELECT 1 FROM integers2 WHERE k = i.i);
-- Rows from left where match exists in rightSELECT DISTINCT integers.*FROM integers INNER JOIN integers2 ON integers.i = integers2.k;-- Alternative: INSELECT *FROM integers WHERE i IN (SELECT k FROM integers2);-- Alternative: EXISTS (usually fastest)SELECT *FROM integers iWHERE EXISTS ( SELECT 1 FROM integers2 WHERE k = i.i);