MERGE en SQL: qué es, cómo funciona y ejemplos prácticos

La sentencia MERGE en SQL se utiliza para sincronizar dos tablas en una sola instrucción.
Permite INSERTAR, ACTUALIZAR o ELIMINAR registros según si existe o no una coincidencia entre ambas tablas.

👉 En otras palabras, es como combinar INSERT, UPDATE y DELETE en una única consulta, lo que hace que sea muy útil en procesos de integración de datos, migraciones o sincronización de sistemas.

Sintaxis básica de MERGE

La sintaxis puede variar un poco según el motor de base de datos, pero la forma general es:

MERGE INTO tabla_destino AS d
USING tabla_origen AS s
ON (condición_de_union)
WHEN MATCHED THEN
    UPDATE SET d.columna = s.columna
WHEN NOT MATCHED THEN
    INSERT (col1, col2, ...)
    VALUES (s.col1, s.col2, ...);

Elementos clave:

  • tabla_destino → la tabla que queremos actualizar.
  • tabla_origen → la tabla (o subconsulta) con los datos de referencia.
  • ON → condición para emparejar registros.
  • WHEN MATCHED → qué hacer si las filas coinciden.
  • WHEN NOT MATCHED → qué hacer si no hay coincidencia.

Ejemplo básico de MERGE

Supongamos que tenemos estas tablas:

empleados_actual

idnombresalario
1Ana2000
2Luis2500
3Carla2800

empleados_nuevos

idnombresalario
2Luis2700
3Carla2800
4Marta2200

Queremos actualizar salarios si el empleado ya existe y agregar los nuevos.

MERGE INTO empleados_actual AS d
USING empleados_nuevos AS s
ON (d.id = s.id)
WHEN MATCHED THEN
    UPDATE SET d.salario = s.salario
WHEN NOT MATCHED THEN
    INSERT (id, nombre, salario)
    VALUES (s.id, s.nombre, s.salario);

Resultado en empleados_actual:

idnombresalario
1Ana2000
2Luis2700
3Carla2800
4Marta2200

👉 Se actualizó el salario de Luis, se insertó a Marta y Carla quedó igual.

MERGE con DELETE

Algunos motores permiten también eliminar registros que no tienen correspondencia:

MERGE INTO empleados_actual AS d
USING empleados_nuevos AS s
ON (d.id = s.id)
WHEN MATCHED AND s.salario IS NULL THEN
    DELETE
WHEN MATCHED THEN
    UPDATE SET d.salario = s.salario
WHEN NOT MATCHED THEN
    INSERT (id, nombre, salario)
    VALUES (s.id, s.nombre, s.salario);

👉 Borra de empleados_actual los registros que aparecen en empleados_nuevos con salario NULL.

Diferencias entre MERGE y otros comandos

  • INSERT + UPDATE manual
UPDATE ... WHERE EXISTS
INSERT ... WHERE NOT EXISTS

👉 Con MERGE se hace en un solo paso.

  • UPSERT
    Es un término usado para “insertar si no existe, actualizar si existe”.
    En PostgreSQL y MySQL (8+) se hace con INSERT ... ON CONFLICT o INSERT ... ON DUPLICATE KEY.
    MERGE es más completo, ya que también permite DELETE.
  • JOIN
    JOIN solo combina datos para leer.
    MERGE modifica datos de la tabla destino.

MERGE en distintos motores de bases de datos

  • SQL Server: soporta MERGE.
  • Oracle: soporta MERGE desde hace años.
  • PostgreSQL: desde la versión 15 soporta MERGE. Antes se emulaba con INSERT ... ON CONFLICT.
  • MySQL: no soporta MERGE. Se usa INSERT ... ON DUPLICATE KEY UPDATE.
  • SQLite: soporta INSERT ... ON CONFLICT, pero no MERGE.

👉 Por eso, antes de usar MERGE, siempre hay que confirmar la compatibilidad del motor.

Casos de uso de MERGE

  1. Sincronización de tablas
    Mantener tabla_destino actualizada con cambios de tabla_origen.
  2. Carga incremental de datos (ETL)
    Actualizar registros existentes e insertar los nuevos.
  3. Migraciones entre sistemas
    Consolidar datos de diferentes fuentes en una sola tabla.
  4. Gestión de catálogos
    Actualizar precios, nombres o inventario desde tablas de proveedores.

Ejemplo avanzado: sincronizar inventario

inventario_actual

producto_idstock
110
25
30

inventario_nuevo

producto_idstock
112
30
420

Consulta:

MERGE INTO inventario_actual d
USING inventario_nuevo s
ON (d.producto_id = s.producto_id)
WHEN MATCHED THEN
    UPDATE SET d.stock = s.stock
WHEN NOT MATCHED THEN
    INSERT (producto_id, stock)
    VALUES (s.producto_id, s.stock);

Resultado:

producto_idstock
112
25
30
420

👉 Se actualizó el stock de producto 1, se insertó el producto 4 y se mantuvo el resto.

Errores comunes con MERGE

  1. Falta de índices en las columnas de unión (ON)
    👉 Puede generar bajo rendimiento.
  2. Confusión entre filas duplicadas en la tabla origen
    👉 Puede causar errores si la condición ON no garantiza unicidad.
  3. Uso incorrecto de condiciones en WHEN MATCHED
    👉 Puede actualizar o borrar filas no deseadas.
  4. Asumir que todos los motores soportan MERGE
    👉 En MySQL y SQLite no existe.

Buenas prácticas con MERGE

  • Asegurarse de que la condición ON sea única.
  • Usar WHEN MATCHED AND ... para controlar actualizaciones o eliminaciones específicas.
  • Probar primero con SELECT antes de aplicar MERGE.
  • Documentar las reglas de negocio detrás de la sincronización.
  • Considerar usar UPSERT cuando solo se necesiten inserciones/actualizaciones.

Preguntas frecuentes (FAQ)

1. ¿MERGE es parte del estándar SQL?
Sí, desde SQL:2003. Pero no todos los motores lo implementan.

2. ¿Puedo usar MERGE para borrar filas?
Sí, usando WHEN MATCHED THEN DELETE.

3. ¿Qué diferencia hay con UPSERT?
UPSERT solo inserta o actualiza. MERGE también permite eliminar.

4. ¿Qué pasa si hay múltiples coincidencias en ON?
Puede generar error o comportamiento inesperado. Es clave asegurar que ON sea único.

5. ¿MySQL soporta MERGE?
No. Debe usarse INSERT ... ON DUPLICATE KEY UPDATE o REPLACE.

Conclusión

La sentencia MERGE en SQL es una de las formas más eficientes de sincronizar tablas y mantener consistencia de datos.

  • Permite INSERT, UPDATE y DELETE en una sola consulta.
  • Es ideal para ETL, integraciones y migraciones.
  • No está disponible en todos los motores, pero donde existe, simplifica mucho el código.

Dominar MERGE es clave para quienes trabajan con grandes volúmenes de datos y necesitan procesos de actualización confiables.

Relaciona esta operación con DML en INSERT, UPDATE y DELETE y vuelve al Glosario SQL completo.

Scroll al inicio