¿Cómo puedo hacer una instrucción UPDATE con JOIN in SQL?
Necesito actualizar esta tabla en SQL Server 2005 con los datos de su tabla 'padre', ver a continuación:
Sale
id (int)
udid (int)
assid (int)
Ud
id (int)
assid (int)
sale.assid
contiene el valor correcto a actualizar ud.assid
.
¿Qué consulta hará esto? Estoy pensando en un join
pero no estoy seguro de si es posible.
14 answers
La sintaxis depende estrictamente de qué DBMS SQL esté utilizando. Aquí hay algunas maneras de hacerlo en ANSI/ISO (también conocido como debería funcionar en cualquier DBMS SQL), MySQL, SQL Server y Oracle. Tenga en cuenta que mi método ANSI/ISO sugerido normalmente será mucho más lento que los otros dos métodos, pero si está utilizando un DBMS SQL que no sea MySQL, SQL Server u Oracle, entonces puede ser el único camino a seguir (por ejemplo, si su DBMS SQL no admite MERGE
):
ANSI / ISO:
update ud
set assid = (
select sale.assid
from sale
where sale.udid = ud.id
)
where exists (
select *
from sale
where sale.udid = ud.id
);
MySQL:
update ud u
inner join sale s on
u.id = s.udid
set u.assid = s.assid
SQL Servidor:
update u
set u.assid = s.assid
from ud u
inner join sale s on
u.id = s.udid
Oráculo:
update
(select
u.assid as new_assid,
s.assid as old_assid
from ud u
inner join sale s on
u.id = s.udid) up
set up.new_assid = up.old_assid
SQLite:
update ud
set assid = (
select sale.assid
from sale
where sale.udid = ud.id
)
where RowID in (
select RowID
from ud
where sale.udid = ud.id
);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-13 20:14:44
Esto debería funcionar en SQL Server:
update ud
set assid = sale.assid
from sale
where sale.udid = id
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-31 19:32:50
Postgres
UPDATE table1
SET COLUMN = value
FROM table2,
table3
WHERE table1.column_id = table2.id
AND table1.column_id = table3.id
AND table1.COLUMN = value
AND table2.COLUMN = value
AND table3.COLUMN = value
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-09 13:26:21
Un enfoque SQL estándar sería
UPDATE ud
SET assid = (SELECT assid FROM sale s WHERE ud.id=s.id)
En SQL Server se puede utilizar un join
UPDATE ud
SET assid = s.assid
FROM ud u
JOIN sale s ON u.id=s.id
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-18 12:34:52
CREATE TABLE ud (id integer, assid integer);
CREATE TABLE sales (id integer, udid integer, assid integer);
UPDATE ud
SET assid = sales.assid
FROM sales
WHERE sales.id = ud.id;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-08 07:52:18
Consulta de actualización simplificada usando JOIN-ing múltiples tablas.
UPDATE
first_table ft
JOIN second_table st ON st.some_id = ft.some_id
JOIN third_table tt ON tt.some_id = st.some_id
.....
SET
ft.some_column = some_value
WHERE ft.some_column = 123456 AND st.some_column = 123456
Nota - first_table, second_table, third_table y some_column como 123456 son nombres de tabla de demostración, nombres de columna e identificadores. Reemplácelos con los nombres válidos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-14 07:15:25
Otro ejemplo de por qué SQL no es realmente portable.
Para MySQL sería:
update ud, sale
set ud.assid = sale.assid
where sale.udid = ud.id;
Para obtener más información, lea actualización de tabla múltiple: http://dev.mysql.com/doc/refman/5.0/en/update.html
UPDATE [LOW_PRIORITY] [IGNORE] table_references
SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
[WHERE where_condition]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-16 19:17:16
Teradata Aster ofrece otra forma interesante de lograr el objetivo:
MERGE INTO ud --what trable should be updated
USING sale -- from what table/relation update info should be taken
ON ud.id = sale.udid --join condition
WHEN MATCHED THEN
UPDATE SET ud.assid = sale.assid; -- how to update
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-03 10:22:18
Estaba pensando que el SQL-Server uno en el post superior funcionaría para Sybase, ya que ambos son T-SQL, pero desafortunadamente no.
Para Sybase encontré que la actualización debe estar en la propia tabla, no en el alias:
update ud
set u.assid = s.assid
from ud u
inner join sale s on
u.id = s.udid
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-19 08:24:18
La siguiente instrucción con la palabra clave FROM se usa para actualizar varias filas con una combinación
UPDATE users
set users.DivisionId=divisions.DivisionId
from divisions join users on divisions.Name=users.Division
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-06 11:34:28
MySQL
Obtendrá el mejor rendimiento si olvida la cláusula where y coloca todas las condiciones en la expresión ON.
Creo que esto se debe a que la consulta primero tiene que unir las tablas y luego ejecuta la cláusula where en eso, por lo que si puede reducir lo que se requiere para unirse, entonces esa es la forma rápida de obtener los resultados/hacer el udpate.
Ejemplo
Escenario
Tienes una tabla de usuarios. Pueden iniciar sesión usando su nombre de usuario o correo electrónico o número de cuenta. Estas cuentas pueden estar activas (1) o inactivas (0). Esta tabla tiene 50000 filas
Luego tienes una tabla de usuarios para desactivar de una sola vez porque descubres que todos han hecho algo malo. Sin embargo, esta tabla tiene una columna con nombres de usuario, correos electrónicos y números de cuenta mezclados. También tiene un indicador "has_run" que necesita ser establecido en 1 (true) cuando se ha ejecutado
Consulta
UPDATE users User
INNER JOIN
blacklist_users BlacklistUser
ON
(
User.username = BlacklistUser.account_ref
OR
User.email = BlacklistedUser.account_ref
OR
User.phone_number = BlacklistUser.account_ref
AND
User.is_active = 1
AND
BlacklistUser.has_run = 0
)
SET
User.is_active = 0,
BlacklistUser.has_run = 1;
Razonamiento
Si tuviéramos que unirnos solo en las condiciones de quirófano, esencialmente necesitaría: compruebe cada fila 4 veces para ver si debe unirse, y potencialmente devolver muchas más filas. Sin embargo, al darle más condiciones, puede "saltar" muchas filas si no cumplen todas las condiciones al unirse.
Bono
Es más legible. Todas las condiciones están en un solo lugar y las filas a actualizar están en un solo lugar
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-09 16:57:54
UPDATE tblAppraisalBasicData
SET tblAppraisalBasicData.ISCbo=1
FROM tblAppraisalBasicData SI INNER JOIN aaa_test RAN ON SI.EmpID = RAN.ID
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-19 11:40:06
Y en MS ACCESS:
UPDATE ud
INNER JOIN sale ON ud.id = sale.udid
SET ud.assid = sale.assid;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-07 18:38:28
Para SQLite use la propiedad RowID para hacer la actualización:
update Table set column = 'NewValue'
where RowID =
(select t1.RowID from Table t1
join Table t2 fd on t1.JoinField = t2.JoinField
where t2.SelectValue = 'FooMyBarPlease');
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-13 14:45:29