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
| id | nombre | salario |
|---|---|---|
| 1 | Ana | 2000 |
| 2 | Luis | 2500 |
| 3 | Carla | 2800 |
empleados_nuevos
| id | nombre | salario |
|---|---|---|
| 2 | Luis | 2700 |
| 3 | Carla | 2800 |
| 4 | Marta | 2200 |
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:
| id | nombre | salario |
|---|---|---|
| 1 | Ana | 2000 |
| 2 | Luis | 2700 |
| 3 | Carla | 2800 |
| 4 | Marta | 2200 |
👉 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 conINSERT ... ON CONFLICToINSERT ... ON DUPLICATE KEY.MERGEes más completo, ya que también permiteDELETE. - JOIN
JOINsolo combina datos para leer.MERGEmodifica datos de la tabla destino.
MERGE en distintos motores de bases de datos
- SQL Server: soporta
MERGE. - Oracle: soporta
MERGEdesde hace años. - PostgreSQL: desde la versión 15 soporta
MERGE. Antes se emulaba conINSERT ... ON CONFLICT. - MySQL: no soporta
MERGE. Se usaINSERT ... ON DUPLICATE KEY UPDATE. - SQLite: soporta
INSERT ... ON CONFLICT, pero noMERGE.
👉 Por eso, antes de usar MERGE, siempre hay que confirmar la compatibilidad del motor.
Casos de uso de MERGE
- Sincronización de tablas
Mantenertabla_destinoactualizada con cambios detabla_origen. - Carga incremental de datos (ETL)
Actualizar registros existentes e insertar los nuevos. - Migraciones entre sistemas
Consolidar datos de diferentes fuentes en una sola tabla. - Gestión de catálogos
Actualizar precios, nombres o inventario desde tablas de proveedores.
Ejemplo avanzado: sincronizar inventario
inventario_actual
| producto_id | stock |
|---|---|
| 1 | 10 |
| 2 | 5 |
| 3 | 0 |
inventario_nuevo
| producto_id | stock |
|---|---|
| 1 | 12 |
| 3 | 0 |
| 4 | 20 |
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_id | stock |
|---|---|
| 1 | 12 |
| 2 | 5 |
| 3 | 0 |
| 4 | 20 |
👉 Se actualizó el stock de producto 1, se insertó el producto 4 y se mantuvo el resto.
Errores comunes con MERGE
- Falta de índices en las columnas de unión (
ON)
👉 Puede generar bajo rendimiento. - Confusión entre filas duplicadas en la tabla origen
👉 Puede causar errores si la condiciónONno garantiza unicidad. - Uso incorrecto de condiciones en WHEN MATCHED
👉 Puede actualizar o borrar filas no deseadas. - Asumir que todos los motores soportan MERGE
👉 En MySQL y SQLite no existe.
Buenas prácticas con MERGE
- Asegurarse de que la condición
ONsea ú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
UPSERTcuando 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.