jueves, 16 de abril de 2009

Update masivo, UPDATE FROM JOIN

Hoy vi algo en SQL que nunca me había imagino que se podía hacer asi


UPDATE dbo.Table2
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
FROM dbo.Table2
INNER JOIN dbo.Table1
ON (dbo.Table2.ColA = dbo.Table1.ColA);


O sea que podemos updatear el valor de una columna de la tabla 1 usando el valor de una columna de otra tabla, haciendo el join entre las tablas con los criterios que usamos en cualquier JOIN. Obviamente tambien puede agregarse un WHERE para filtrar los registros que queremos updatear.

Lo único que me suena raro lo saque del artículo de Wikipedia de UPDATE

The SQL:2003 standard does not support updates of a joined table. Therefore, the following method needs to be used. Note that the subselect in the SET clause must be a scalar subselect, i.e., it can return at most a single row.
UPDATE T1
SET C1 = ( SELECT T2.C2
FROM T2
WHERE T1.ID = T2.ID )
WHERE EXISTS ( SELECT 1
FROM T2
WHERE T1.ID = T2.ID )


En SQLSERVER 2000 funciona el UPDATE FROM JOIN. El método que propone la wiki eno se me había ocurrido, pero es muy bueno también, y además claramente es válido en ANSI SQL.
Respecto de la claridad de cada statemente, depende de si uno esta acostumbrado al UPDATE FROM JOIN o no, ya que este parece raro a primera vista. En cambio, la segunda versión es más natural ya que es similar a un UPDATE típico (recordar que para poder poner un subquery dentro del SET de un UPDATE este subquery deber ser escalar, es decir, retornar un solo registro y una sola columna)

Además, las misma técnicas pueden usarse con DELETE.
Y finalmente, aunque obviamente es más conocido, no olvidemos que para INSERT masivo siempre este el viejo INSERT INTO tabla (col1, col2, ... ) SELECT

1 comentario:

Anónimo dijo...

En efecto es una de las bondades de sql server son inmensamente mas rapidas que los cursores u otro tipo de recorridos y precisamente buscando una solucion como esta pero en el motor de informix me doy cuenta que no funciona de la misma manera que lastima...saludos