Data modification & MERGE
Concept  ·  SQL & Querying

INSERT ... SELECT matches by position, not name — a reordered SELECT silently loads the wrong columns (P07 atom in DML costume).

This is positional_alignment (P07) with higher stakes: a query's wrong rows vanish on the next run, but an INSERT's wrong rows persist — discovered weeks later, mixed with correct rows, needing forensic cleanup. SELECT * feeding an INSERT is the same bug on a timer: it works until someone reorders or adds a column in either table's DDL.

See it break
intake
roomitem
westlamp
archive
itemroom
The trap
INSERT INTO
  archive SELECT
  *
FROM
  intake;

SELECT
  item,
  room
FROM
  archive;
The fix
INSERT INTO
  archive (item, room)
SELECT
  item,
  room
FROM
  intake;

SELECT
  item,
  room
FROM
  archive;
INPUTYour queryThe fix
westlampwest

The nightly load committed 'west' into the item column — INSERT ... SELECT * mapped intake's columns into archive by position, and the room name is now stored as an item, permanently.

The rule

Explicit column lists, both sides, always — INSERT INTO t (a, b) SELECT x, y; no SELECT * into INSERTs.

Shows up elsewhere
Set ops align by positionIdempotent upsert
Try one →Prove it in practice →