Curso de SQL completo: SELECT, JOIN, agregaciones, índices y transacciones (2026)

INSERT INTO es la instrucción para añadir filas a una tabla. Se puede insertar una sola fila, varias filas a la vez o el resultado de un SELECT en otra tabla. MySQL ofrece además variantes para gestionar conflictos cuando una fila duplicada intenta insertarse.

En este capítulo cubrimos la sintaxis completa del INSERT, las inserciones masivas, INSERT ... SELECT, y las opciones IGNORE y ON DUPLICATE KEY UPDATE para manejar claves duplicadas.

INSERT básico: una fila

-- Sintaxis con nombres de columna (recomendada: clara y resistente a cambios de esquema)
INSERT INTO clientes (nombre, email, ciudad, fecha_alta)
VALUES ('Pedro Sanz', '[email protected]', 'Granada', '2026-05-09');

-- La columna 'id' es AUTO_INCREMENT: no la incluimos, MySQL la genera automáticamente

-- Sintaxis corta sin nombres de columna (frágil: depende del orden exacto de columnas)
INSERT INTO clientes VALUES (NULL, 'Pedro Sanz', '[email protected]', 'Granada', '2026-05-09');

LAST_INSERT_ID: obtener el ID generado

INSERT INTO pedidos (id_cliente, estado) VALUES (1, 'pendiente');
SELECT LAST_INSERT_ID();  -- devuelve el id AUTO_INCREMENT del último INSERT

-- Útil cuando debes insertar el ID en otra tabla a continuación:
INSERT INTO pedidos (id_cliente, estado) VALUES (1, 'pendiente');
SET @nuevo_pedido_id = LAST_INSERT_ID();
INSERT INTO lineas_pedido (id_pedido, id_producto, cantidad, precio_ud)
VALUES (@nuevo_pedido_id, 2, 3, 8.99);

INSERT múltiple: varias filas en un solo INSERT

-- Mucho más eficiente que un INSERT por fila
INSERT INTO categorias (nombre) VALUES
    ('Electrónica'),
    ('Ropa'),
    ('Hogar'),
    ('Deportes');

INSERT INTO productos (nombre, precio, stock, id_categoria) VALUES
    ('Auriculares Bluetooth',  59.99, 120, 1),
    ('Cable USB-C 2m',          8.99, 500, 1),
    ('Camiseta algodón M',     12.50,  80, 2),
    ('Lámpara de escritorio',  34.95,  45, 3);

-- En MySQL, el INSERT múltiple ejecuta en una sola transacción implícita
-- y es significativamente más rápido que N INSERTs separados

INSERT ... SELECT: copiar datos de otra tabla

-- Insertar los clientes de Madrid en una tabla de clientes_vip
INSERT INTO clientes_vip (nombre, email, ciudad, fecha_alta)
SELECT nombre, email, ciudad, fecha_alta
FROM clientes
WHERE ciudad = 'Madrid';

-- Crear una tabla de respaldo con los datos de hoy
INSERT INTO pedidos_backup
SELECT * FROM pedidos WHERE DATE(fecha) = CURDATE();

INSERT IGNORE: ignorar errores de duplicado

-- Sin IGNORE, esto fallaría si el email ya existe (columna UNIQUE)
INSERT INTO clientes (nombre, email, ciudad, fecha_alta)
VALUES ('Ana García', '[email protected]', 'Madrid', '2026-05-09');
-- ERROR 1062: Duplicate entry '[email protected]' for key 'email'

-- Con IGNORE, el error se convierte en una advertencia y se omite la fila
INSERT IGNORE INTO clientes (nombre, email, ciudad, fecha_alta)
VALUES ('Ana García', '[email protected]', 'Madrid', '2026-05-09');
-- No falla, simplemente no inserta (rows affected: 0)

ON DUPLICATE KEY UPDATE: insertar o actualizar

-- Si el email ya existe, actualiza el nombre y la ciudad en lugar de fallar
INSERT INTO clientes (nombre, email, ciudad, fecha_alta)
VALUES ('Ana García Nuevas', '[email protected]', 'Málaga', '2026-05-09')
ON DUPLICATE KEY UPDATE
    nombre = VALUES(nombre),
    ciudad = VALUES(ciudad);

-- Patrón "upsert": insertar si no existe, actualizar si existe
-- Útil para cachés, contadores, configuraciones por clave
INSERT INTO contadores (clave, valor)
VALUES ('visitas_hoy', 1)
ON DUPLICATE KEY UPDATE valor = valor + 1;

REPLACE INTO: variante destructiva del upsert (MySQL)

-- REPLACE primero borra la fila existente (si hay duplicado) y luego inserta
-- CUIDADO: genera un nuevo AUTO_INCREMENT y dispara triggers de DELETE + INSERT
REPLACE INTO categorias (id, nombre) VALUES (1, 'Electrónica y accesorios');

-- Generalmente es mejor usar ON DUPLICATE KEY UPDATE
-- que conserva el ID original y es más predecible

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP