SQL SERVER – 4 Formas de actualizar registros con el resultado de una consulta.

Un escenario común es el de actualizar los registros de una tabla con los datos devueltos por una consulta, así que en esta breve entrada mostraré 4 maneras de actualizar registros de una tabla con el resultado de una consulta usando SubConsultas, Joins y WITH.

*** Importante, será necesario usar la base de datos AdventureWorks tratada en este artículo: Attach y Dettach en SQL Server 2012

Imaginemos que la empresa, a sabiendas de la ardua labor del departamento de ingeniería decide otorgar a todo el personal de ese departamento dos horas adicionales a sus vacaciones. 

La primera forma de resolverlo, aunque  ineficiente, es usando una subconsulta para validar con IN qué registros son aplicables de ser actualizados:

UPDATE HumanResources.Employee 
   SET VacationHours =  VacationHours + 2
 WHERE EmployeeID IN (
              select EMPLEADO.EmployeeID
                FROM HumanResources.Employee EMPLEADO
           LEFT JOIN HumanResources.EmployeeDepartmentHistory DEPARTAMENTO
                  ON EMPLEADO.EmployeeID = DEPARTAMENTO.EmployeeID
               WHERE EndDate is null and
                     DEPARTAMENTO.DepartmentID = 1  
       )

La segunda forma, más eficiente por cierto,  genera una subconsulta que será tratada como tabla derivada permitiendo establecer un Join implícito entre la tabla destino y la consulta.

UPDATE HumanResources.Employee
   SET VacationHours =  VacationHours + 2
  FROM (      SELECT EMPLEADO.EmployeeID
                FROM HumanResources.Employee EMPLEADO
           LEFT JOIN HumanResources.EmployeeDepartmentHistory DEPARTAMENTO
                  ON EMPLEADO.EmployeeID = DEPARTAMENTO.EmployeeID
               WHERE EndDate is null and
                     DEPARTAMENTO.DepartmentID = 1  
        ) FILTRO
  WHERE HumanResources.Employee.EmployeeID = FILTRO.EmployeeID

La tercera forma es haciendo uso de Joins en la sentencia de actualización. Aquí es posible establecer un alias para la tabla derivada y usarlo en el Update. De esa manera se establece que las filas por actualizar serán aquellas que coincidan con los criterios del Join y el where. 

        UPDATE EMPLEADO
           SET EMPLEADO.VacationHours =  EMPLEADO.VacationHours + 2
          FROM HumanResources.Employee EMPLEADO
     LEFT JOIN HumanResources.EmployeeDepartmentHistory DEPARTAMENTO
            ON EMPLEADO.EmployeeID = DEPARTAMENTO.EmployeeID
         WHERE EndDate is null and
               DEPARTAMENTO.DepartmentID = 1

 

Esta consulta de actualización es igual a la tercera, solo aprovecha el inner join para omitir el where 

        UPDATE EMPLEADO
           SET EMPLEADO.VacationHours =  EMPLEADO.VacationHours + 2
          FROM HumanResources.Employee EMPLEADO
    INNER JOIN HumanResources.EmployeeDepartmentHistory DEPARTAMENTO
            ON EMPLEADO.EmployeeID = DEPARTAMENTO.EmployeeID AND
               EndDate is null and
               DEPARTAMENTO.DepartmentID = 1

y por último, podemos hacer uso de una expresión de tabla común (CTE) para establecer el rango de filas por actualizar.

      WITH EMPLEADO AS (
                           SELECT EMPLEADO.*
                             FROM HumanResources.Employee EMPLEADO
                       INNER JOIN HumanResources.EmployeeDepartmentHistory DEPARTAMENTO
                               ON EMPLEADO.EmployeeID = DEPARTAMENTO.EmployeeID AND
                                  EndDate is null and
                                  DEPARTAMENTO.DepartmentID = 1  
                        )

        UPDATE EMPLEADO
           SET EMPLEADO.VacationHours =  EMPLEADO.VacationHours + 2

Si deseas saber más acerca de esto, puedes leer la documentación oficial.

Sé el primero en comentar

Deja un comentario