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.

Author: Ant Swift, 2009-08-18

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
 );
 2501
Author: Eric,
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
 147
Author: edosoft,
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 
 101
Author: user1154043,
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
 51
Author: MattH,
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

PostgreSQL:

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;
 39
Author: alfonx,
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.

 26
Author: Vinit Kadkol,
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]
 16
Author: Yada,
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
 10
Author: xhudik,
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
 8
Author: Ken Goh,
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 miejscu
 8
Author: Luke Watts,
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-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
 7
Author: Sheryar Nizar,
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
 5
Author: Kemal AL GAZZAH,
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;
 4
Author: Richard,
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
 3
Author: Abdullah Yousuf,
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');
 3
Author: KeithTheBiped,
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
 3
Author: HARSHIT RATHORE,
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