tablas - ¿Actualizar una tabla usando JOIN en SQL Server?
update dos tablas sql server (10)
Quiero actualizar una columna en una tabla haciendo una unión en otra tabla, por ejemplo:
UPDATE table1 a
INNER JOIN table2 b ON a.commonfield = b.[common field]
SET a.CalculatedColumn= b.[Calculated Column]
WHERE
b.[common field]= a.commonfield
AND a.BatchNO = ''110''
Pero se queja:
Mensaje 170, Nivel 15, Estado 1, Línea 2
Línea 2: Sintaxis incorrecta cerca de ''a''.
¿Que esta mal aquí?
La respuesta dada arriba por Aaron es perfecta:
UPDATE a
SET a.CalculatedColumn = b.[Calculated Column]
FROM Table1 AS a
INNER JOIN Table2 AS b
ON a.CommonField = b.[Common Field]
WHERE a.BatchNo = ''110'';
Solo quiero agregar por qué este problema se produce en SQL Server cuando intentamos usar el alias de una tabla al actualizar esa tabla, la siguiente sintaxis de mención siempre dará un error:
update tableName t
set t.name = ''books new''
where t.id = 1
case puede ser any si está actualizando una sola tabla o actualizando mientras usa join.
Aunque la consulta anterior funcionará bien en PL / SQL pero no en SQL Server.
La forma correcta de actualizar una tabla mientras se usa el alias de tabla en SQL Server es:
update t
set t.name = ''books new''
from tableName t
where t.id = 1
Espero que ayude a todos por qué vino aquí el error.
Me parece útil convertir una ACTUALIZACIÓN en un SELECCIONAR para obtener las filas que deseo actualizar como prueba antes de actualizar. Si puedo seleccionar las filas exactas que quiero, puedo actualizar solo las filas que quiero actualizar.
DECLARE @expense_report_id AS INT
SET @expense_report_id = 1027
--UPDATE expense_report_detail_distribution
--SET service_bill_id = 9
SELECT *
FROM expense_report_detail_distribution erdd
INNER JOIN expense_report_detail erd
INNER JOIN expense_report er
ON er.expense_report_id = erd.expense_report_id
ON erdd.expense_report_detail_id = erd.expense_report_detail_id
WHERE er.expense_report_id = @expense_report_id
Otro enfoque sería utilizar MERGE.
;WITH cteTable1(CalculatedColumn, CommonField)
AS
(
select CalculatedColumn, CommonField from Table1 Where BatchNo = ''110''
)
MERGE cteTable1 AS target
USING (select "Calculated Column", "Common Field" FROM dbo.Table2) AS source ("Calculated Column", "Common Field")
ON (target.CommonField = source."Common Field")
WHEN MATCHED THEN
UPDATE SET target.CalculatedColumn = source."Calculated Column";
-Merge es parte del estándar SQL
-También estoy bastante seguro de que las actualizaciones de la combinación interna no son deterministas ... Una pregunta similar aquí donde la respuesta habla de eso http://ask.sqlservercentral.com/questions/19089/updating-two-tables-using-single-query.html
Parece que SQL Server 2012 también puede manejar la antigua sintaxis de actualización de Teradata:
UPDATE a
SET a.CalculatedColumn= b.[Calculated Column]
FROM table1 a, table2 b
WHERE
b.[common field]= a.commonfield
AND a.BatchNO = ''110''
Si recuerdo correctamente, 2008R2 estaba dando error cuando intenté una consulta similar.
Pruébalo así:
begin tran
UPDATE a
SET a.CalculatedColumn= b.[Calculated Column]
FROM table1 a INNER JOIN table2 b ON a.commonfield = b.[common field]
WHERE a.BatchNO = ''110''
commit tran
(Edit: ¡malditos errores!)
Tratar:
UPDATE table1
SET CalculatedColumn = ( SELECT [Calculated Column]
FROM table2
WHERE table1.commonfield = [common field])
WHERE BatchNO = ''110''
Tuve el mismo problema ... y no es necesario que agregue una columna física ... porque ahora tendrá que mantenerla ... lo que puede hacer es agregar una columna genérica en la consulta de selección:
EX:
select tb1.col1, tb1.col2, tb1.col3 ,
(
select ''Match'' from table2 as tbl2
where tbl1.col1 = tbl2.col1 and tab1.col2 = tbl2.col2
)
from myTable as tbl1
Usted no tiene la sintaxis de UPDATE FROM
el propietario de SQL Server. Tampoco estoy seguro de por qué necesitabas unirte en CommonField
y también filtrarlo después. Prueba esto:
UPDATE t1
SET t1.CalculatedColumn = t2.[Calculated Column]
FROM dbo.Table1 AS t1
INNER JOIN dbo.Table2 AS t2
ON t1.CommonField = t2.[Common Field]
WHERE t1.BatchNo = ''110'';
Si estás haciendo algo realmente tonto, como intentar constantemente establecer el valor de una columna en el agregado de otra columna (lo que viola el principio de evitar el almacenamiento de datos redundantes), puedes usar un CTE (expresión de tabla común) :
;WITH t2 AS
(
SELECT [key], CalculatedColumn = SUM(some_column)
FROM dbo.table2
GROUP BY [key]
)
UPDATE t1
SET t1.CalculatedColumn = t2.CalculatedColumn
FROM dbo.table1 AS t1
INNER JOIN t2
ON t1.[key] = t2.[key];
La razón por la que esto es realmente tonto, es que tendrá que volver a ejecutar esta actualización completa cada vez que table2
una fila en la table2
. Una SUM
es algo que siempre se puede calcular en tiempo de ejecución y, al hacerlo, nunca tiene que preocuparse de que el resultado sea obsoleto.
UPDATE mytable
SET myfield = CASE other_field
WHEN 1 THEN ''value''
WHEN 2 THEN ''value''
WHEN 3 THEN ''value''
END
From mytable
Join otherTable on otherTable.id = mytable.id
Where othertable.somecolumn = ''1234''
Más alternativas aquí: http://www.karlrixon.co.uk/writing/update-multiple-rows-with-different-values-and-a-single-sql-query/
MERGE table1 T
USING table2 S
ON T.CommonField = S."Common Field"
AND T.BatchNo = ''110''
WHEN MATCHED THEN
UPDATE
SET CalculatedColumn = S."Calculated Column";