Como hacer un update de SQL Server a partir de una query self-join

A la hora de hacer un update de SQL Server, el lenguaje SQL nos ofrece muchas posibilidades, y una de las más potentes es realizar el update a partir de una join de la tabla que actualizamos con otra tabla de la base de datos, que contiene la información de lo que necesitamos actualizar.

Update con self join SQL Server

 

Update con join en SQL Server

Este tipo de update se puede resolver, tal como Héctor apuntaba en el tema del foro Update con join en SQL Server con una query tan simple como esta:

UPDATE FAC_TABLE
SET COSTE_UNITARIO = ct.COSTE_UNITARIO
FROM COSTES ct
WHERE FAC_TABLE.id_articulo = ct.id_articulo

 o su equivalente con la INNER JOIN explícita:

UPDATE FAC_TABLE
SET COSTE_UNITARIO = ct.COSTE_UNITARIO
FROM FAC_TABLE fac
INNER JOIN COSTES ct
ON fac.id_articulo = ct.id_articulo

 

Update con self-join en SQL Server

Pero hay un caso en el que estas sentencias de update a partir de una select, si las dejamos tal como están, no funcionarían bien y nos devolverían un error. Estas sentencia de update no sirven si la tabla con la que hacemos la join es la misma que queremos actualizar, es decir, si queremos hacer un update con una self-join.

Por ejemplo, imaginemos que disponemos de una tabla de empleados en la que tenemos informado para cada uno el id del jefe de su departamento, que como trabajamos con la tabla de todos los empleados de la empresa no es más que otro empleado que está en la misma tabla, y tenemos en la esta tabla de empleados otro campo con el nombre del responsable, que queremos informar o actualizar. Para hacerlo podríamos probar con una sentencia de Update con selfjoin como esta:

UPDATE DIM_EMPLEADO  
SET JefeDepartamento = emp2.NombreEmpleado  
FROM DIM_EMPLEADO emp  
INNER JOIN DIM_EMPLEADO emp2 
    ON emp.id_JefeDepartamento = emp2.id_Empleado

Pero el resultado del servidor SQL Server sería un mensaje de error como éste:

Mens. 8154, Nivel 16, Estado 1, Línea 1
La tabla 'DIM_EMPLEADO' es ambigua.

 

La solución es sencilla, sobretodo cuando te la explican :).

Si hacemos un update de una tabla una self join con la misma tabla, hay que incluir el alias de la tabla en la 'linea de update' de la sentencia, no sólo en la parte del FROM. Así el analizador de SQLServer ya no se lía y actualiza correctamente con los datos de la select contra la misma tabla que queremos actualizar:

UPDATE DIM_EMPLEADO emp  
SET JefeDepartamento = emp2.NombreEmpleado  
FROM DIM_EMPLEADO emp  
INNER JOIN DIM_EMPLEADO emp2
     ON emp.id_JefeDepartamento = emp2.id_Empleado

 

Por Carlos Fernández

 

¿Te ha resultado útil este tip? Utiliza el botón de 'SHARE' para que también sea útil a los demás.

 

 Desde el grupo SQL Server Si! Ricardo Scheffer aporta otra sencilla solución para poder hacer un update con selfjoin, reproduzco su aportación:

Realizando las siguientes consultas sobre la AdventureWorksLT2008R2, donde las siguientes situaciones no se presentan y son bastantes sencillas, simplemente usamos el recorrido absoluto. 

update SalesLT.Customer
  set SalesLT.Customer.FirstName = t.FirstName
  from SalesLT.Customer as t
  where CustomerID = t.CustomerID  

O con sintaxis INNER Join:

UPDATE SalesLT.Customer
  SET SalesLT.Customer.FirstName = t.FirstName
  FROM SalesLT.Customer
  INNER JOIN SalesLT.Customer as t
  ON SalesLT.Customer.CustomerID = t.CustomerID