Обновление SQL из одной таблицы в другую на основе идентификатора

У меня есть база данных с account numbers и card numbers . Я сопоставляю их с файлом на update номера карт на номер учетной записи, так что я работаю только с номерами счетов.

Я создал представление, связывающее таблицу с базой данных учетной записи / карты, чтобы вернуть номер Table ID и соответствующий номер учетной записи, и теперь мне нужно обновить те записи, где идентификатор совпадает с номером учетной записи.

Это таблица Sales_Import , в которой необходимо обновить поле account number :

 LeadID  AccountNumber
147         5807811235
150         5807811326
185         7006100100007267039
 

И это таблица RetrieveAccountNumber , где мне нужно обновить:

 LeadID  AccountNumber
147         7006100100007266957
150         7006100100007267039
 

Я попробовал ниже, но пока не повезло:

 UPDATE [Sales_Lead].[dbo].[Sales_Import] 
SET    [AccountNumber] = (SELECT RetrieveAccountNumber.AccountNumber 
                          FROM   RetrieveAccountNumber 
                          WHERE  [Sales_Lead].[dbo].[Sales_Import]. LeadID = 
                                                RetrieveAccountNumber.LeadID) 
 

Он обновляет номера карт по номерам счетов, но номера учетных записей заменяются на card numbers

вопрос задан 22.10.2008
Scott McKenzie
7408 репутация

19 ответов


  • 1143 рейтинг

    Я считаю, что UPDATE FROM с JOIN поможет:

    MS SQL

     UPDATE
        Sales_Import
    SET
        Sales_Import.AccountNumber = RAN.AccountNumber
    FROM
        Sales_Import SI
    INNER JOIN
        RetrieveAccountNumber RAN
    ON 
        SI.LeadID = RAN.LeadID;
     

    MySQL и MariaDB

     UPDATE
        Sales_Import SI,
        RetrieveAccountNumber RAN
    SET
        SI.AccountNumber = RAN.AccountNumber
    WHERE
        SI.LeadID = RAN.LeadID;
     
    ответ дан Mark S. Rasmussen, с репутацией 26220, 22.10.2008
  • 257 рейтинг

    Простой способ скопировать содержимое из одной таблицы в другую:

     UPDATE table2 
    SET table2.col1 = table1.col1, 
    table2.col2 = table1.col2,
    ...
    FROM table1, table2 
    WHERE table1.memberid = table2.memberid
     

    Вы также можете добавить условие для копирования конкретных данных.

    ответ дан Shivkant, с репутацией 3366, 20.01.2010
  • 145 рейтинг

    Для SQL Server 2008 + использование MERGE а не проприетарный синтаксис UPDATE ... FROM имеет некоторую привлекательность.

    Помимо стандартного SQL и, следовательно, более портативного, это также вызовет ошибку в случае наличия нескольких связанных строк на стороне источника (и, следовательно, нескольких возможных разных значений для использования в обновлении), а не окончательного результата без детерминизма ,

     MERGE INTO Sales_Import
       USING RetrieveAccountNumber
          ON Sales_Import.LeadID = RetrieveAccountNumber.LeadID
    WHEN MATCHED THEN
       UPDATE 
          SET AccountNumber = RetrieveAccountNumber.AccountNumber;
     

    К сожалению, выбор, который можно использовать, возможно, не сводится только к предпочитаемому стилю. Реализация MERGE в SQL Server была затронута различными ошибками. Аарон Бертран составил список зарегистрированных здесь .

    ответ дан Martin Smith, с репутацией 333672, 11.02.2012
  • 46 рейтинг

    Общий ответ для будущих разработчиков.

    SQL Server

     UPDATE 
         t1
    SET 
         t1.column = t2.column
    FROM 
         Table1 t1 
         INNER JOIN Table2 t2 
         ON t1.id = t2.id;
     

    Oracle (и SQL Server)

     UPDATE 
         t1
    SET 
         t1.colmun = t2.column 
    FROM 
         Table1 t1, 
         Table2 t2 
    WHERE 
         t1.ID = t2.ID;
     

    MySQL

     UPDATE 
         Table1 t1, 
         Table2 t2
    SET 
         t1.column = t2.column 
    WHERE
         t1.ID = t2.ID;
     
    ответ дан Tigerjz32, с репутацией 2141, 29.08.2016
  • 33 рейтинг

    Кажется, вы используете MSSQL, тогда, если я правильно помню, это делается следующим образом:

     UPDATE [Sales_Lead].[dbo].[Sales_Import] SET [AccountNumber] = 
    RetrieveAccountNumber.AccountNumber 
    FROM RetrieveAccountNumber 
    WHERE [Sales_Lead].[dbo].[Sales_Import].LeadID = RetrieveAccountNumber.LeadID
     
    ответ дан Vinko Vrsalovic, с репутацией 199051, 22.10.2008
  • 28 рейтинг

    У меня была та же проблема, при которой foo.new был установлен в null для строк из foo , у которых не было подходящего ключа в bar . Я сделал что-то подобное в Oracle:

    обновить foo
    set foo.new = (выберите bar.new
                      из бара 
                      где foo.key = bar.key)
    где существует (выберите 1
                  из бара
                  где foo.key = bar.key)
    
    ответ дан Kjell Andreassen, с репутацией 614, 29.04.2009
  • 25 рейтинг

    Для PostgreSQL:

     UPDATE Sales_Import SI
    SET AccountNumber = RAN.AccountNumber
    FROM RetrieveAccountNumber RAN
    WHERE RAN.LeadID = SI.LeadID; 
     
    ответ дан petter, с репутацией 975, 16.07.2014
  • 24 рейтинг

    Для MySql, который отлично работает:

     UPDATE
        Sales_Import SI,RetrieveAccountNumber RAN
    SET
        SI.AccountNumber = RAN.AccountNumber
    WHERE
        SI.LeadID = RAN.LeadID
     
    ответ дан marsanvi, с репутацией 482, 13.02.2012
  • 14 рейтинг

    Спасибо за ответы. Я нашел решение tho.

     UPDATE Sales_Import 
    SET    AccountNumber = (SELECT RetrieveAccountNumber.AccountNumber 
                              FROM   RetrieveAccountNumber 
                              WHERE  Sales_Import.leadid =RetrieveAccountNumber.LeadID) 
    WHERE Sales_Import.leadid = (SELECT  RetrieveAccountNumber.LeadID 
                                 FROM   RetrieveAccountNumber 
                                 WHERE  Sales_Import.leadid = RetrieveAccountNumber.LeadID)  
     
    ответ дан Vinko Vrsalovic, с репутацией 199051, 22.10.2008
  • 3 рейтинг

    обновление в пределах одной таблицы:

       DECLARE @TB1 TABLE
        (
            No Int
            ,Name NVarchar(50)
            ,linkNo int
        )
    
        DECLARE @TB2 TABLE
        (
            No Int
            ,Name NVarchar(50)
            ,linkNo int
        )
    
        INSERT INTO @TB1 VALUES(1,'changed person data',  0);
        INSERT INTO @TB1 VALUES(2,'old linked data of person', 1);
    
    INSERT INTO @TB2 SELECT * FROM @TB1 WHERE linkNo = 0
    
    
    SELECT * FROM @TB1
    SELECT * FROM @TB2
    
    
        UPDATE @TB1 
            SET Name = T2.Name
        FROM        @TB1 T1
        INNER JOIN  @TB2 T2 ON T2.No = T1.linkNo
    
        SELECT * FROM @TB1
     
    ответ дан NCP, с репутацией 49, 6.12.2012
  • 2 рейтинг

    Предложенный ниже SQL-запрос не работает в SQL Server. Этот синтаксис напоминает мне мой старый школьный класс:

     UPDATE table2 
    SET table2.col1 = table1.col1, 
    table2.col2 = table1.col2,
    ...
    FROM table1, table2 
    WHERE table1.memberid = table2.memberid
     

    Все остальные запросы с использованием NOT IN или NOT EXISTS не рекомендуется. Отображаются NULL, потому что OP сравнивает весь набор данных с меньшим подмножеством, тогда, конечно, будет проблема соответствия. Это необходимо исправить, написав правильный SQL с правильной JOIN вместо проблемы уклонения, используя NOT IN . В этом случае вы можете столкнуться с другими проблемами, используя NOT IN или NOT EXISTS .

    Мой голос за верхний, который является обычным способом обновления таблицы на основе другой таблицы путем присоединения к SQL Server. Как я уже сказал, вы не можете использовать две таблицы в одном выражении UPDATE в SQL Server, если вы не присоедините их первым.

    ответ дан Dr Inner Join, с репутацией 37, 12.06.2016
  • 2 рейтинг

    он работает с postgresql

     UPDATE application
    SET omts_received_date = (
        SELECT
            date_created
        FROM
            application_history
        WHERE
            application.id = application_history.application_id
        AND application_history.application_status_id = 8
    );
     
    ответ дан jakentus, с репутацией 680, 14.05.2015
  • 1 рейтинг

    Используйте следующий блок запроса для обновления таблицы 1 с таблицей 2 на основе идентификатора:

     UPDATE Sales_Import, RetrieveAccountNumber 
    SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber 
    where Sales_Import.LeadID = RetrieveAccountNumber.LeadID;
     

    Это самый простой способ решить эту проблему.

    ответ дан Gil Baggio, с репутацией 1867, 12.11.2017
  • 1 рейтинг

    Я думал, что это простой пример, если кому-то это станет легче,

             DECLARE @TB1 TABLE
            (
                No Int
                ,Name NVarchar(50)
            )
    
            DECLARE @TB2 TABLE
            (
                No Int
                ,Name NVarchar(50)
            )
    
            INSERT INTO @TB1 VALUES(1,'asdf');
            INSERT INTO @TB1 VALUES(2,'awerq');
    
    
            INSERT INTO @TB2 VALUES(1,';oiup');
            INSERT INTO @TB2 VALUES(2,'lkjhj');
    
            SELECT * FROM @TB1
    
            UPDATE @TB1 SET Name =S.Name
            FROM @TB1 T
            INNER JOIN @TB2 S
                    ON S.No = T.No
    
            SELECT * FROM @TB1
     
    ответ дан user824910, с репутацией 440, 4.06.2012
  • -1 рейтинг

    Это позволит вам обновить таблицу на основе значения столбца, которое не будет найдено в другой таблице.

         UPDATE table1 SET table1.column = 'some_new_val' WHERE table1.id IN (
                SELECT * 
                FROM (
                        SELECT table1.id
                        FROM  table1 
                        LEFT JOIN table2 ON ( table2.column = table1.column ) 
                        WHERE table1.column = 'some_expected_val'
                        AND table12.column IS NULL
                ) AS Xalias
        )
     

    Это обновит таблицу, основанную на значении столбца, которое будет найдено в обеих таблицах.

         UPDATE table1 SET table1.column = 'some_new_val' WHERE table1.id IN (
                SELECT * 
                FROM (
                        SELECT table1.id
                        FROM  table1 
                        JOIN table2 ON ( table2.column = table1.column ) 
                        WHERE table1.column = 'some_expected_val'
                ) AS Xalias
        )
     
    ответ дан CG_DEV, с репутацией 506, 2.04.2015
  • -1 рейтинг

    попробуй это :

     UPDATE
        Table_A
    SET
        Table_A.AccountNumber = Table_B.AccountNumber ,
    FROM
        dbo.Sales_Import AS Table_A
        INNER JOIN dbo.RetrieveAccountNumber AS Table_B
            ON Table_A.LeadID = Table_B.LeadID 
    WHERE
        Table_A.LeadID = Table_B.LeadID
     
    ответ дан Oriel.F, с репутацией 305, 14.11.2016
  • -1 рейтинг

    Вот что я работал в SQL Server:

     UPDATE [AspNetUsers] SET
    
    [AspNetUsers].[OrganizationId] = [UserProfile].[OrganizationId],
    [AspNetUsers].[Name] = [UserProfile].[Name]
    
    FROM [AspNetUsers], [UserProfile]
    WHERE [AspNetUsers].[Id] = [UserProfile].[Id];
     
    ответ дан Abhimanyu, с репутацией 815, 7.09.2018
  • -2 рейтинг

    Если вышеприведенные ответы не работают для вас, попробуйте это

     Update Sales_Import A left join RetrieveAccountNumber B on A.LeadID = B.LeadID
    Set A.AccountNumber = B.AccountNumber
    where A.LeadID = B.LeadID 
     
    ответ дан Shaw, с репутацией 12, 10.01.2018
  • -2 рейтинг

    Я хотел бы добавить еще одну вещь.

    Не обновляйте значение с тем же значением, оно генерирует дополнительные записи и ненужные накладные расходы. См. Пример ниже - он будет выполнять обновление только на 2 записи, несмотря на ссылку на 3.

     DROP TABLE #TMP1
    DROP TABLE #TMP2
    CREATE TABLE #TMP1(LeadID Int,AccountNumber NVarchar(50))
    CREATE TABLE #TMP2(LeadID Int,AccountNumber NVarchar(50))
    
    INSERT INTO #TMP1 VALUES
    (147,'5807811235')
    ,(150,'5807811326')
    ,(185,'7006100100007267039');
    
    INSERT INTO #TMP2 VALUES
    (147,'7006100100007266957')
    ,(150,'7006100100007267039')
    ,(185,'7006100100007267039');
    
    UPDATE A
    SET A.AccountNumber = B.AccountNumber
    FROM
        #TMP1 A 
            INNER JOIN #TMP2 B
            ON
            A.LeadID = B.LeadID
    WHERE
        A.AccountNumber <> B.AccountNumber  --DON'T OVERWRITE A VALUE WITH THE SAME VALUE
    
    SELECT * FROM #TMP1
     
    ответ дан pacreely, с репутацией 1571, 13.12.2016