NATURAL JOIN
A NATURAL JOIN automatically joins two tables on all columns that share the same name, without an explicit ON or USING clause.
Overview
NATURAL JOIN joins two tables based on every column they have in common by name, without needing an explicit ON or USING clause -- DuckDB infers the join condition automatically from matching column names.
Copy code
SELECT *
FROM orders
NATURAL JOIN customers;
-- equivalent to: JOIN customers USING (customer_id), if customer_id is the only shared column
This is equivalent to writing orders JOIN customers USING (customer_id) when customer_id is the only column name shared between both tables. If the tables share multiple column names, all of them are used as join keys.
Why NATURAL JOIN is risky
The convenience comes with a real hazard: NATURAL JOIN's behavior depends entirely on the current column names of both tables, which can change over time. If someone later adds a new column to either table that happens to share a name with a column in the other table (e.g., both tables gain a created_at or updated_at column), the join condition silently changes to include that column too -- potentially breaking the query's results without any error, and without the change being visible at the query site itself.
Because of this fragility, NATURAL JOIN is generally discouraged in production code in favor of being explicit:
Copy code
-- safer and more explicit than NATURAL JOIN
SELECT *
FROM orders
JOIN customers USING (customer_id);
NATURAL JOIN vs USING vs ON
NATURAL JOIN: implicit join columns, inferred from shared column names across both tables.JOIN ... USING (col): explicit join columns, but still requires the column to share the same name on both sides; only one copy of eachUSINGcolumn appears in the output.JOIN ... ON condition: fully explicit condition, with no naming constraints; both tables' versions of any equated column remain in the output as usual.
DuckDB notes
DuckDB supports NATURAL JOIN per the standard, along with NATURAL LEFT JOIN and other join type variants, but USING is generally the recommended middle ground -- explicit about which columns are join keys, while still avoiding duplicate output columns.
Related terms
The USING clause specifies join columns by name when both tables share identically named columns, joining on equality and returning a single copy of each shared column.
JOIN clause →How do SQL JOINs work? Learn INNER, LEFT, RIGHT, FULL OUTER, CROSS, and ASOF joins with syntax examples — plus how to join directly against CSV and Parquet files.
CROSS JOIN →A CROSS JOIN produces the Cartesian product of two tables, pairing every row from the first table with every row from the second.
SELF JOIN →A self join joins a table to itself, typically using table aliases to compare rows within the same table to each other.
ASOF JOIN →An ASOF JOIN matches each row in one table to the closest preceding (or following) row in another table based on an ordering column, commonly a timestamp -- a core building block for time-series analysis.
Natural key →A natural key is an identifier that comes from real-world business data — like an email address, SSN, or product SKU — as opposed to a surrogate key generated purely for database use.
FAQS
It infers join columns from whichever column names happen to match between the two tables at query time, so adding an unrelated same-named column to either table later can silently change the join's behavior without any warning.
NATURAL JOIN automatically determines the join columns from every shared column name; USING requires you to explicitly list which shared-name columns to join on, making the join condition visible and stable.
Yes -- DuckDB supports NATURAL LEFT JOIN, NATURAL RIGHT JOIN, and other join type combinations with the same implicit shared-column matching.
