Как я могу сделать инструкцию UPDATE с JOIN в SQL?
мне нужно обновить эту таблицу в SQL Server 2005 С данными из таблицы "родитель" см. ниже:
продажа
id (int)
udid (int)
assid (int)
ud
id (int)
assid (int)
sale.assid
содержит правильное значение для обновления ud.assid
.
какой запрос сделает это? Я думаю join
но я не уверен, если это возможно.
14 ответов
синтаксис строго зависит от того, какие СУБД SQL вы используете. Вот несколько способов сделать это в ANSI/ISO (aka должен работать на любой СУБД SQL), MySQL, SQL Server и Oracle. Обратите внимание, что мой предлагаемый метод ANSI / ISO обычно будет намного медленнее, чем два других метода, но если вы используете СУБД SQL, отличную от MySQL, SQL Server или Oracle ,то это может быть единственный способ (например, если ваша СУБД SQL не поддерживает 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 Server:
update u
set u.assid = s.assid
from ud u
inner join sale s on
u.id = s.udid
Oracle:
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
);
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
стандартный подход SQL будет
UPDATE ud
SET assid = (SELECT assid FROM sale s WHERE ud.id=s.id)
на SQL Server вы можете использовать join
UPDATE ud
SET assid = s.assid
FROM ud u
JOIN sale s ON u.id=s.id
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;
упрощенный запрос обновления с помощью вступить - ing несколько таблиц.
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
Примечание - first_table, second_table, third_table и some_column как 123456 имена демонстрационных таблиц, имена столбцов и идентификаторы. Замените их действительными именами.
еще один пример, почему SQL на самом деле не переносится.
для MySQL это было бы:
update ud, sale
set ud.assid = sale.assid
where sale.udid = ud.id;
для получения дополнительной информации прочитайте обновление нескольких таблиц: 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]
Teradata Aster предлагает еще один интересный способ достижения цели:
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
Я думал, что SQL-сервер в верхнем посте будет работать для Sybase, так как они оба T-SQL, но, к сожалению, нет.
для Sybase я обнаружил, что обновление должно быть на самой таблице, а не псевдоним:
update ud
set u.assid = s.assid
from ud u
inner join sale s on
u.id = s.udid
следующий оператор с ключевым словом FROM используется для обновления нескольких строк с помощью join
UPDATE users
set users.DivisionId=divisions.DivisionId
from divisions join users on divisions.Name=users.Division
в MySQL
вы получите лучшую производительность, если забудете предложение where и поместите все условия в выражение ON.
Я думаю, это потому, что запрос сначала должен присоединиться к таблицам, затем запускает предложение where на этом, поэтому, если вы можете уменьшить то, что требуется для присоединения, то это быстрый способ получить результаты/сделать udpate.
пример
сценарий
у вас есть таблица пользователей. Они могут войти, используя свое имя пользователя или email или account_number. Эти учетные записи могут быть активными (1) или неактивными (0). Эта таблица имеет 50000 строк
затем у вас есть таблица пользователей, чтобы отключить на одном дыхании, потому что вы узнаете, что они все сделали что-то плохое. Однако в этой таблице есть один столбец с именами пользователей, электронными письмами и номерами счетов. Он также имеет индикатор "has_run", который должен быть установлен в 1 (true), когда он был запущен
запрос
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;
мышление
Если бы нам пришлось присоединиться только в условиях OR необходимо будет проверить каждую строку 4 раза, чтобы увидеть, следует ли ей присоединиться, и потенциально вернуть намного больше строк. Однако, давая ему больше условий, он может "пропустить" много строк, если они не соответствуют всем условиям при присоединении.
бонус
Это более читабельным. Все условия находятся в одном месте, а строки для обновления-в одном месте
UPDATE tblAppraisalBasicData
SET tblAppraisalBasicData.ISCbo=1
FROM tblAppraisalBasicData SI INNER JOIN aaa_test RAN ON SI.EmpID = RAN.ID
для SQLite используйте свойство RowID для обновления:
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');