SQL differences

FULL OUTER JOIN Works on PostgreSQL and SQLite and Fails on MySQL and MariaDB

Matching two lists, such as invoices and payments, to see what is missing on either side calls for a FULL OUTER JOIN. PostgreSQL and SQLite run it, and MySQL and MariaDB refuse it.

MySQL and MariaDB have LEFT and RIGHT joins only. SQLite added RIGHT and FULL joins in version 3.39.

SELECT a.x, b.x FROM a FULL OUTER JOIN b ON a.x = b.x, run on four engines: SQLite 3.45.1 1, NULL; 2, 2; NULL, 3; PostgreSQL 16.15 1, NULL; 2, 2; NULL, 3; MySQL 8.0.46 error: You have an error in your SQL syntax ... near 'OUTER JOIN b ON a.x = b.x' at line 1; MariaDB 10.11.14 error: You have an error in your SQL syntax ... near 'OUTER JOIN b ON a.x = b.x' at line 1.

What Each Engine Answered

On a table made with

CREATE TABLE a (x INTEGER);
CREATE TABLE b (x INTEGER);
INSERT INTO a VALUES (1), (2);
INSERT INTO b VALUES (2), (3);

the example

SELECT a.x, b.x FROM a FULL OUTER JOIN b ON a.x = b.x;

gave these answers:

Engine Answer
SQLite 3.45.1 1, NULL; 2, 2; NULL, 3
PostgreSQL 16.15 1, NULL; 2, 2; NULL, 3
MySQL 8.0.46 error: You have an error in your SQL syntax ... near 'OUTER JOIN b ON a.x = b.x' at line 1
MariaDB 10.11.14 error: You have an error in your SQL syntax ... near 'OUTER JOIN b ON a.x = b.x' at line 1

These answers need SQLite 3.39 or later.

What to Write Instead

This form answers the same on every engine:

SELECT a.x, b.x FROM a LEFT JOIN b ON a.x = b.x UNION ALL SELECT a.x, b.x FROM b LEFT JOIN a ON a.x = b.x WHERE a.x IS NULL;
Engine Answer
SQLite 3.45.1 1, NULL; 2, 2; NULL, 3
PostgreSQL 16.15 1, NULL; 2, 2; NULL, 3
MySQL 8.0.46 1, NULL; 2, 2; NULL, 3
MariaDB 10.11.14 2, 2; 1, NULL; NULL, 3

Combine a LEFT JOIN with the rows of the other table that found no match: ... FROM a LEFT JOIN b ON a.x = b.x UNION ALL SELECT ... FROM b LEFT JOIN a ON a.x = b.x WHERE a.x IS NULL.

What BareSQL Portable Reports

Saved as example.sql, the example gets this from baresql lint --all:

$ baresql lint --all example.sql
example.sql:5:24: error: FULL OUTER JOIN works on SQLite and PostgreSQL; MySQL and MariaDB refuse it. [full-outer-join]
    FULL OUTER
    Combine a LEFT JOIN with the rows of the other table that found no match: ... FROM a LEFT JOIN b ON a.x = b.x UNION ALL SELECT ... FROM b LEFT JOIN a ON a.x = b.x WHERE a.x IS NULL.

1 problem: 1 error.

baresql rules full-outer-join prints the same answers in the terminal, and the BareSQL Portable page lists every difference BareSQL knows.