Pembaruan SQL dari satu Tabel ke yang lain berdasarkan pencocokan ID

929

Saya memiliki database dengan account numbersdan card numbers. Saya mencocokkan ini dengan file ke updatenomor kartu apa saja dengan nomor akun, sehingga saya hanya bekerja dengan nomor akun.

Saya membuat tampilan yang menghubungkan tabel ke database akun / kartu untuk mengembalikan Table IDdan nomor akun terkait, dan sekarang saya perlu memperbarui catatan-catatan di mana ID cocok dengan Nomor Akun.

Ini adalah Sales_Importtabel, di mana account numberbidang perlu diperbarui:

LeadID  AccountNumber
147         5807811235
150         5807811326
185         7006100100007267039

Dan ini adalah RetrieveAccountNumbertabel, tempat saya perlu memperbarui dari:

LeadID  AccountNumber
147         7006100100007266957
150         7006100100007267039

Saya mencoba di bawah ini, tetapi tidak berhasil sejauh ini:

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

Ini memperbarui nomor kartu ke nomor akun, tetapi nomor akun diganti oleh NULL

DineshDB
sumber

Jawaban:

1369

Saya percaya sebuah UPDATE FROMdengan JOINkehendak bantuan:

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 dan MariaDB

UPDATE
    Sales_Import SI,
    RetrieveAccountNumber RAN
SET
    SI.AccountNumber = RAN.AccountNumber
WHERE
    SI.LeadID = RAN.LeadID;
Mark S. Rasmussen
sumber
18
Anda mungkin ingin menggunakan alias tabel dalam klausa UPDATE, jika tidak maka akan menyebabkan masalah jika Anda sendiri bergabung dengan tabel pada titik mana pun.
Tom H
15
Dalam klausa yang ditetapkan Anda harus mengubah SI.AccountNumberke hanya AccountNumbersebaliknya itu akan gagal.
AaronLS
1
MS-Access menggunakan UPDATE yang berbeda dengan Pernyataan GABUNG. Lihatlah: sql-und-xml.de/sql-tutorial/…
Christian Ammer
92
ini tampaknya baik untuk mssql tetapi tampaknya tidak berfungsi di mysql. Hal ini tampaknya untuk melakukan pekerjaan meskipun: UPDATE Sales_Import, RetrieveAccountNumber SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber where Sales_Import.LeadID = RetrieveAccountNumber.LeadID;. Agak topik tapi mungkin membantu
Edd
7
Saya pikir tidak perlu untuk batin bergabung. Solusi Vonki di bawah ini bekerja: UPDATE [Sales_Lead] [dbo] [Sales_Import] SET [ACCOUNTNUMBER] = RetrieveAccountNumber.AccountNumber DARI RetrieveAccountNumber WHERE [Sales_Lead] [dbo] [Sales_Import] .LeadID = RetrieveAccountNumber.LeadID....
Gutti
289

Cara sederhana untuk menyalin konten dari satu tabel ke tabel lainnya adalah sebagai berikut:

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

Anda juga dapat menambahkan ketentuan untuk menyalin data tertentu.

Shivkant
sumber
2
Ini berfungsi, tetapi Anda tidak perlu table2 di FROM UPDATE table2 SET table2.col1 = table1.col1, table2.col2 = table1.col2, ... FROM table1 WHERE table1.memberid = table2.memberid
Sirentec
2
Ini tidak berhasil, tetapi UPDATE table2, table1 SET table2.col1 = table1.col1, ... WHERE table1.memberid = table2.memberid (mysql dan phpmyadmin)
Tom Kuschel
156

Untuk SQL Server 2008 + Menggunakan MERGEdaripada milikUPDATE ... FROM sintaksis memiliki beberapa daya tarik.

Serta menjadi SQL standar dan dengan demikian lebih portabel juga akan meningkatkan kesalahan jika ada beberapa baris yang bergabung di sisi sumber (dan dengan demikian beberapa kemungkinan nilai yang berbeda untuk digunakan dalam pembaruan) daripada memiliki hasil akhir yang tidak ditentukan. .

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

Sayangnya pilihan yang akan digunakan mungkin tidak sepenuhnya turun ke gaya yang disukai. Implementasi MERGEdalam SQL Server telah mengalami berbagai bug. Aaron Bertrand telah menyusun daftar yang dilaporkan di sini .

Martin Smith
sumber
11
Menuju ke depan MERGE.
Jakub Januszkiewicz
2
Saya tidak pernah tahu tentang sintaks gabungan. Ini jauh lebih bersih daripada Pembaruan + Bergabung.
Tony Ashworth
+1 untuk pelaporan implementasi SQL Server MERGE
AFract
1
Argumen untuk menggunakan MERGE (termasuk yang ada di pos dari sqlblog.com yang ditautkan di atas) mungkin menarik, tetapi satu hal yang perlu dipertimbangkan mungkin bahwa menurut MSDN : ... Pernyataan MERGE bekerja paling baik ketika kedua tabel memiliki campuran kompleks antara mencocokkan karakteristik ... Ketika hanya memperbarui satu tabel berdasarkan baris dari tabel lain, peningkatan kinerja dan skalabilitas dapat dicapai dengan pernyataan INSERT, UPDATE, dan DELETE dasar
Tony Pulokas
1
@ jkp1187 Pertanyaan ini ditandai dengan SQL Server. Jadi RE: FWIW - sekitar nol.
Martin Smith
104

Jawaban umum untuk pengembang masa depan.

SQL Server

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

Oracle (dan 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
sumber
2
Dari catatan setidaknya untuk SQL Server, gunakan alias daripada nama tabel dalam klausa pembaruan teratas ( update t1...bukan update Table1...)
gordon
2
Versi Oracle tidak berfungsi. Mendapatkan ORA-00933
ka3ak
35

Untuk PostgreSQL:

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

Sepertinya Anda menggunakan MSSQL, maka, jika saya ingat dengan benar, dilakukan seperti ini:

UPDATE [Sales_Lead].[dbo].[Sales_Import] SET [AccountNumber] = 
RetrieveAccountNumber.AccountNumber 
FROM RetrieveAccountNumber 
WHERE [Sales_Lead].[dbo].[Sales_Import].LeadID = RetrieveAccountNumber.LeadID
Vinko Vrsalovic
sumber
33

Saya memiliki masalah yang sama dengan foo.newdiatur ke nulluntuk baris fooyang tidak memiliki kunci yang cocok bar. Saya melakukan sesuatu seperti ini di Oracle:

perbarui foo
set foo.new = (pilih bar.new
                  dari bar 
                  dimana foo.key = bar.key)
di mana ada (pilih 1
              dari bar
              dimana foo.key = bar.key)
Kjell Andreassen
sumber
4
Mengapa WHERE EXISTS diperlukan?
Georg Schölly
6
Karena setiap baris di foo tidak memiliki kecocokan di bilah akhirnya menjadi nol, karena pernyataan pilih menghasilkan nol. Semoga ini lebih jelas daripada upaya pertama saya menjelaskannya.
Kjell Andreassen
periksa jawaban ini di bawah stackoverflow.com/questions/224732/…
Basheer AL-MOMANI
@KjellAndreassen Anda telah memecahkan masalah saya. Terima kasih untuk kodemu.
Bhavin Thummar
27

Untuk MySql yang berfungsi dengan baik:

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

Inilah yang bekerja untuk saya di SQL Server:

UPDATE [AspNetUsers] SET

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

FROM [AspNetUsers], [UserProfile]
WHERE [AspNetUsers].[Id] = [UserProfile].[Id];
Abimanyu
sumber
18

Terima kasih atas tanggapannya. Saya menemukan solusi untuk itu.

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)  
Martin Smith
sumber
17
Apakah kode di sini berfungsi atau tidak, Anda mungkin harus melihat dua solusi lain yang diposting. Mereka jauh lebih jelas dan jauh lebih rentan terhadap kesalahan serta hampir pasti lebih cepat.
Tom H
3
Hanya catatan pada solusi ini, PEMBARUAN ... DARI karena itu milik, jika Anda tidak dapat menggunakan pernyataan MERGE karena Anda menggunakan SQL 2005 atau sebelumnya, ini adalah metode ANSI-compliant untuk melakukan pembaruan dengan sumber tabel di MSSQL. Sumber: sqlblog.com/blogs/hugo_kornelis/archive/2008/03/10/…
pseudocoder
1
satu-satunya solusi yang bekerja untuk saya karena itu adalah pernyataan pembaruan SQL standar (UPDATE SET WHERE), terima kasih banyak
Basheer AL-MOMANI
13

Dalam hal tabel berada dalam database yang berbeda. (MSSQL)

update database1..Ciudad
set CiudadDistrito=c2.CiudadDistrito

FROM database1..Ciudad c1
 inner join 
  database2..Ciudad c2 on c2.CiudadID=c1.CiudadID
Maurico Bello
sumber
10

Gunakan blok permintaan berikut untuk memperbarui Table1 dengan Table2 berdasarkan ID:

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

Ini adalah cara termudah untuk mengatasi masalah ini.

Gil Baggio
sumber
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';

Oracle 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  ;
salman samadi
sumber
3

perbarui dalam tabel yang sama:

  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
sumber
3

Seseorang SQL di bawah ini menyarankan, TIDAK bekerja di SQL Server. Sintaks ini mengingatkan saya pada kelas sekolah lama saya:

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

Semua pertanyaan lain menggunakan NOT INatau NOT EXISTStidak direkomendasikan. NULLs muncul karena OP membandingkan seluruh dataset dengan subset yang lebih kecil, maka tentu saja akan ada masalah yang cocok. Ini harus diperbaiki dengan menulis SQL yang tepat dengan benar JOINalih-alih menghindari masalah dengan menggunakan NOT IN. Anda mungkin mengalami masalah lain dengan menggunakan NOT INatauNOT EXISTS dalam kasus ini.

Pilihan saya untuk yang teratas, yang merupakan cara konvensional untuk memperbarui tabel berdasarkan tabel lain dengan bergabung dalam SQL Server. Seperti saya katakan, Anda tidak dapat menggunakan dua tabel dalam UPDATEpernyataan yang sama di SQL Server kecuali jika Anda bergabung terlebih dahulu.

Dr Inner Bergabung
sumber
2
Saya hanya bisa mengatakan bahwa di SQL Server 2017 ini berfungsi dengan baik. Sama seperti catatan untuk orang-orang masa depan yang datang. Tidak perlu bergabung dengan mereka.
SharpShade
3

ia bekerja dengan 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
sumber
1

Saya pikir ini adalah contoh sederhana mungkin seseorang bisa lebih mudah,

        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
pengguna824910
sumber
0

Oracle 11g

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

Ini akan memungkinkan Anda untuk memperbarui tabel berdasarkan nilai kolom yang tidak ditemukan di tabel lain.

    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
    )

Ini akan memperbarui tabel berdasarkan nilai kolom yang ditemukan di kedua tabel.

    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
sumber
-1

coba ini :

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
sumber
-2

Saya ingin menambahkan satu hal tambahan.

Jangan perbarui nilai dengan nilai yang sama, itu menghasilkan logging tambahan dan overhead yang tidak perlu. Lihat contoh di bawah - ini hanya akan melakukan pembaruan pada 2 catatan meskipun tertaut pada 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
sumber
-3

Jika jawaban di atas tidak berfungsi untuk Anda coba ini

Update Sales_Import A left join RetrieveAccountNumber B on A.LeadID = B.LeadID
Set A.AccountNumber = B.AccountNumber
where A.LeadID = B.LeadID 
Shaw
sumber