ID 일치에 따라 한 테이블에서 다른 테이블로 SQL 업데이트


929

나는이있는 데이터베이스를 가지고 account numberscard numbers. 이것들을 파일과 일치시킵니다.update계정 번호로 카드 번호와 번호를 시켜 계정 번호로만 작업하고 있습니다.

테이블을 계정 / 카드 데이터베이스에 연결하여 Table ID및 관련 계정 번호 를 반환하는보기를 만들었으므로 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) 

카드 번호를 계좌 번호로 업데이트하지만 계좌 번호는 NULL

답변:


1368

나는 믿을 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;

18
UPDATE 절에서 테이블 별명을 사용하려고 할 수 있습니다. 그렇지 않으면 언제든지 테이블을 자체 조인하면 문제가 발생할 수 있습니다.
Tom H

15
SET 절에서 당신은 변경해야합니다 SI.AccountNumber단지로 AccountNumber, 그렇지 않으면 실패합니다.
AaronLS

1
MS-Access는 다른 UPDATE with JOIN 문을 사용합니다. sql-und-xml.de/sql-tutorial/…을
Christian Ammer

92
이것은 mssql에는 문제가 없지만 mysql에서는 작동하지 않는 것 같습니다. 이것은 그러나 일을하는 것처럼 보입니다 : UPDATE Sales_Import, RetrieveAccountNumber SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber where Sales_Import.LeadID = RetrieveAccountNumber.LeadID;. 주제를 약간 벗어 났지만 도움이 될 수 있음
Edd

7
내부 조인이 필요하지 않다고 생각합니다. 아래의 Vonki 솔루션 : UPDATE [Sales_Lead]. [dbo]. [Sales_Import] SET [AccountNumber] = RetrieveAccountNumber.AccountNumber FROM RetrieveAccountNumber WHERE [Sales_Lead]. [dbo]. [Sales_Import] .LeadID = RetrieveAccountNumber.LeadID
Gutti

289

한 테이블에서 다른 테이블로 내용을 복사하는 간단한 방법은 다음과 같습니다.

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

조건을 추가하여 특정 데이터를 복사 할 수도 있습니다.


2
이것은 작동하지만 FROM UPDATE table2 SET table2.col1 = table1.col1, table2.col2 = table1.col2, ...에서 table2는 필요하지 않습니다. FROM table1 WHERE table1.memberid = table2.memberid
Sirentec

2
이것은 작동하지 않지만 UPDATE table2, table1 SET table2.col1 = table1.col1, ... WHERE table1.memberid = table2.memberid (mysql 및 phpmyadmin)
Tom Kuschel

156

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;

불행히도 사용할 선택은 순전히 선호하는 스타일로 내려 가지 않을 수 있습니다. MERGESQL Server 의 구현에는 다양한 버그가 있습니다. Aaron Bertrand는 여기에보고 된 것들 의 목록을 편집했습니다 .


11
로 향합니다 MERGE.
Jakub Januszkiewicz

2
병합 구문에 대해 전혀 몰랐습니다. 업데이트 + 가입보다 훨씬 깨끗합니다.
Tony Ashworth

MERGE SQL Server 구현보고에 대한 +1
AFract

1
MERGE ( 위의 링크 된 sqlblog.com의 게시물을 포함)를 사용하는 것에 대한 주장은 설득력이있을 수 있지만 MSDN에 따르면 고려해야 할 사항은 두 가지 테이블에 복잡한 조합이있을 때 가장 잘 작동하는 것입니다
Tony Pulokas

1
@ jkp1187이 질문은 SQL Server로 태그되었습니다. 따라서 RE : FWIW-약 0입니다.
Martin Smith

104

미래 개발자를위한 일반적인 답변.

SQL 서버

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

오라클 (및 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;

2
(상단 업데이트 절에 테이블 이름 대신 별칭을 사용하여 SQL Server에 대한 최소한의 설명의 update t1...대신 update Table1...)
고든

2
Oracle 버전이 작동하지 않습니다. ORA-00933 받기
ka3ak

35

PostgreSQL의 경우 :

UPDATE Sales_Import SI
SET AccountNumber = RAN.AccountNumber
FROM RetrieveAccountNumber RAN
WHERE RAN.LeadID = SI.LeadID; 

34

MSSQL을 사용하고있는 것 같습니다. 정확히 기억하면 다음과 같이 수행됩니다.

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

33

에 일치하는 키가없는 행에 대해 foo.new설정된 것과 동일한 문제 가있었습니다 . Oracle에서 이와 같은 작업을 수행했습니다.nullfoobar

foo 업데이트
foo.new 설정 = (bar.new 선택)
                  바에서 
                  여기서 foo.key = bar.key)
존재하는 곳 (1 번 선택)
              바에서
              여기서 foo.key = bar.key)

4
기존의 장소 가 왜 필요한가요?
Georg Schölly

6
select 문이 null을 생성했기 때문에 foo에서 일치하는 항목이없는 foo의 각 행은 null이되었습니다. 이것이 처음 설명하는 것보다 명확하기를 바랍니다.
Kjell Andreassen


@KjellAndreassen 당신은 내 문제를 해결했습니다. 코드 주셔서 감사합니다.
Bhavin Thummar

27

MySql의 경우 제대로 작동합니다.

UPDATE
    Sales_Import SI,RetrieveAccountNumber RAN
SET
    SI.AccountNumber = RAN.AccountNumber
WHERE
    SI.LeadID = RAN.LeadID

26

SQL Server에서 나를 위해 일한 것은 다음과 같습니다.

UPDATE [AspNetUsers] SET

[AspNetUsers].[OrganizationId] = [UserProfile].[OrganizationId],
[AspNetUsers].[Name] = [UserProfile].[Name]

FROM [AspNetUsers], [UserProfile]
WHERE [AspNetUsers].[Id] = [UserProfile].[Id];

18

답변 주셔서 감사합니다. 해결책을 찾았습니다.

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)  

17
코드가 작동하는지 여부에 관계없이 게시 된 다른 두 가지 솔루션을 살펴보십시오. 그것들은 훨씬 더 명확 할뿐만 아니라 오류가 발생하기 훨씬 쉽고 명확합니다.
Tom H

3
이 솔루션에 대한 참고 사항 인 UPDATE ... FROM은 독점적이므로 SQL 2005 이전 버전을 사용하고 있기 때문에 MERGE 문을 사용할 수없는 경우 이는 MSSQL에서 테이블 소스로 업데이트를 수행하는 ANSI 호환 방법입니다. 출처 : sqlblog.com/blogs/hugo_kornelis/archive/2008/03/10/…
pseudocoder

1
나를 위해 작동하는 유일한 솔루션 때문에 표준 SQL UPDATE 문 (UPDATE의 SET), 덕분에 많이
바시르 AL-MOMANI

13

테이블이 다른 데이터베이스에있는 경우 (MSSQL)

update database1..Ciudad
set CiudadDistrito=c2.CiudadDistrito

FROM database1..Ciudad c1
 inner join 
  database2..Ciudad c2 on c2.CiudadID=c1.CiudadID

10

다음 쿼리 블록을 사용하여 ID를 기반으로 Table1을 Table2로 업데이트하십시오.

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

이것이이 문제를 해결 하는 가장 쉬운 방법 입니다.


8

MS Sql

UPDATE  c4 SET Price=cp.Price*p.FactorRate FROM TableNamea_A c4
inner join TableNamea_B p on c4.Calcid=p.calcid 
inner join TableNamea_A cp on c4.Calcid=cp.calcid 
WHERE c4..Name='MyName';

오라클 11g

        MERGE INTO  TableNamea_A u 
        using
        (
                SELECT c4.TableName_A_ID,(cp.Price*p.FactorRate) as CalcTot 
                FROM TableNamea_A c4
                inner join TableNamea_B p on c4.Calcid=p.calcid 
                inner join TableNamea_A cp on c4.Calcid=cp.calcid 
                WHERE p.Name='MyName' 
        )  rt
        on (u.TableNamea_A_ID=rt.TableNamea_B_ID)
        WHEN MATCHED THEN
        Update set Price=CalcTot  ;

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

3

아래의 누군가가 제안한 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하지 않는 다른 모든 쿼리 OP는 전체 데이터 집합을 더 작은 하위 집합과 비교하기 때문에 NULL이 표시됩니다. 물론 일치하는 문제가 있습니다. JOIN를 사용하여 문제를 피하는 대신 올바른 SQL로 올바른 SQL을 작성하여 수정해야합니다 NOT IN. 당신은 사용하여 다른 문제가 실행될 수 있습니다 NOT IN또는NOT EXISTS 이 경우.

SQL Server에 가입하여 다른 테이블을 기반으로 테이블을 업데이트하는 일반적인 방법 인 최상위에 대한 투표입니다. 내가 말했듯이, UPDATESQL Server의 두 테이블을 먼저 연결하지 않으면 같은 명령문에서 두 테이블을 사용할 수 없습니다 .


2
SQL Server 2017에서는 이것이 완벽하게 작동한다고 말할 수 있습니다. 미래의 사람들을위한 메모처럼. 가입 할 필요가 없습니다.
SharpShade

3

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
);

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

0

오라클 11g

merge into Sales_Import
using RetrieveAccountNumber
on (Sales_Import.LeadId = RetrieveAccountNumber.LeadId)
when matched then update set Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber;

-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
    )

-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

-2

하나 더 추가하고 싶습니다.

동일한 값으로 값을 업데이트하지 않으면 추가 로깅 및 불필요한 오버 헤드가 발생합니다. 아래 예를 참조하십시오-3에 연결하더라도 2 개의 레코드에 대해서만 업데이트를 수행합니다.

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

-3

위의 답변이 효과가 없으면 시도해보십시오.

Update Sales_Import A left join RetrieveAccountNumber B on A.LeadID = B.LeadID
Set A.AccountNumber = B.AccountNumber
where A.LeadID = B.LeadID 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.