Jak mogę wykonać instrukcję aktualizacji za pomocą JOIN in SQL Server?
Muszę zaktualizować tę tabelę w SQL Server danymi z tabeli 'rodzica', patrz poniżej:
Tabela: sprzedaż
id (int)
udid (int)
assid (int)
Tabela: ud
id (int)
assid (int)
sale.assid
zawiera poprawną wartość do aktualizacji ud.assid
.
Jakie zapytanie to zrobi? Myślę o join
, ale nie jestem pewien, czy to możliwe.
16 answers
Składnia ściśle zależy od tego, którego SQL DBMS używasz. Oto kilka sposobów, aby to zrobić w ANSI / ISO (aka powinien działać na dowolnym DBMS SQL), MySQL, SQL Server i Oracle. Należy pamiętać, że moja sugerowana metoda ANSI / ISO będzie zazwyczaj znacznie wolniejsza niż dwie pozostałe metody, ale jeśli używasz SQL DBMS innego niż MySQL, SQL Server lub Oracle, może to być jedyny sposób (np. jeśli twój SQL DBMS nie obsługuje 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 Serwer:
update u
set u.assid = s.assid
from ud u
inner join sale s on
u.id = s.udid
PostgreSQL:
update ud
set assid = s.assid
from sale s
where ud.id = s.udid;
Należy pamiętać, że tabela docelowa nie może być powtarzana w klauzuli FROM
dla Postgres.
Wyrocznia:
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/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-10 03:56:40
To powinno działać w SQL serverze:
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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-09 13:26:21
Standardowe podejście SQL byłoby
UPDATE ud
SET assid = (SELECT assid FROM sale s WHERE ud.id=s.id)
Na SQL Server możesz użyć 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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-08 07:52:18
Uproszczone zapytanie aktualizacyjne za pomocą JOIN - ing wiele tabel.
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
Notatka - first_table, second_table, third_table i some_column jak 123456 są nazwami tabel demo, nazwami kolumn i identyfikatorami. Zastąp je poprawnymi nazwami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-14 07:15:25
Kolejny przykład, dlaczego SQL nie jest tak naprawdę przenośny.
Dla MySQL byłoby to:
update ud, sale
set ud.assid = sale.assid
where sale.udid = ud.id;
Aby uzyskać więcej informacji przeczytaj wiele aktualizacji tabeli: 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/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-16 19:17:16
Teradata Aster oferuje inny ciekawy sposób na osiągnięcie celu:
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/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-03 10:22:18
Myślałem, że ten SQL-Server w górnym poście będzie działał dla Sybase, ponieważ oba są T-SQL, ale niestety nie.
Dla Sybase znalazłem update musi być na samym stole, a nie 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/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-19 08:24:18
MySQL
Najlepszą wydajność uzyskasz, jeśli zapomnisz klauzuli where i umieścisz wszystkie warunki w wyrażeniu ON.
Myślę, że to dlatego, że zapytanie najpierw musi dołączyć do tabel, a następnie uruchamia klauzulę where na to, więc jeśli możesz zmniejszyć to, co jest wymagane, aby dołączyć, to jest szybki sposób, aby uzyskać wyniki / zrobić udpate.
Przykład
Scenariusz
Masz tabelę użytkowników. Mogą się zalogować używając swojej nazwy użytkownika, adresu e-mail lub numeru konta. Konta te mogą być aktywne (1) lub nieaktywne (0). Tabela zawiera 50000 wierszy
Następnie masz tabelę użytkowników do wyłączenia za jednym razem, ponieważ dowiadujesz się, że wszyscy zrobili coś złego. Ta tabela ma jednak jedną kolumnę z mieszanymi nazwami użytkowników, e-mailami i numerami kont. Posiada również wskaźnik "has_run", który musi być ustawiony na 1 (true) po uruchomieniu
Zapytanie
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;
Rozumowanie
Gdybyśmy mieli dołączyć tylko na warunkach RNO, zasadniczo musiałoby to sprawdź każdy wiersz 4 razy, aby zobaczyć, czy powinien się połączyć i potencjalnie zwrócić dużo więcej wierszy. Jednak, dając mu więcej warunków, może "pominąć" wiele wierszy, jeśli nie spełniają wszystkich warunków podczas łączenia.
Bonus
Jest bardziej czytelny. Wszystkie warunki są w jednym miejscu, a wiersze do aktualizacji są w jednym miejscuWarning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-09 16:57:54
Następująca instrukcja ze słowem kluczowym FROM jest używana do aktualizacji wielu wierszy za pomocą join
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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-06 11:34:28
Najprostszym sposobem jest użycie wspólnego wyrażenia tabeli (CTE) wprowadzonego w SQL 2005
with cte as
(select u.assid col1 ,s.assid col2 from ud u inner join sale s on u.id = s.udid)
update cte set col1=col2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-23 17:07:19
Oraz w 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-07 18:38:28
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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-19 11:40:06
Dla SQLite użyj właściwości rowid aby dokonać aktualizacji:
update Table set column = 'NewValue'
where RowID =
(select t1.RowID from Table t1
join Table2 t2 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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-13 16:04:59
Spróbuj tego, myślę, że to zadziała dla ciebie
update ud
set ud.assid = sale.assid
from ud
Inner join sale on ud.id = sale.udid
where sale.udid is not null
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-23 15:42:18