Kimlik eşleşmesine dayalı olarak bir Tablodan diğerine SQL güncelleme


929

Ben bir veritabanı account numbersve card numbers. Bunları bir dosya ile updatehesap numarasının herhangi bir kart numarasıyla eşleştiriyorum , böylece sadece hesap numaralarıyla çalışıyorum.

Tabloyu hesap / kart veritabanına Table IDve ilgili hesap numarasını döndürmek için bağlayan bir görünüm oluşturdum ve şimdi kimliğin Hesap Numarası ile eşleştiği bu kayıtları güncellemem gerekiyor.

Bu Sales_Importtablo, account numberalan güncellenmesi gerekiyor:

LeadID  AccountNumber
147         5807811235
150         5807811326
185         7006100100007267039

Ve bu RetrieveAccountNumbertablo, nerede güncellemeniz gerekir:

LeadID  AccountNumber
147         7006100100007266957
150         7006100100007267039

Aşağıdaki denedim, ama şimdiye kadar şans yok:

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

Kart numaralarını hesap numaralarına günceller, ancak hesap numaralarının yerini NULL

Yanıtlar:


1369

Ben UPDATE FROMbir JOINirade yardımı ile inanıyorum :

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

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

18
UPDATE yan tümcesinde tablo takma adını kullanmak isteyebilirsiniz, aksi takdirde tabloya herhangi bir noktada kendiniz katılırsanız sorunlara neden olur.
Tom H

15
Set madde için değiştirmek gerekir SI.AccountNumberlazım AccountNumberaksi takdirde başarısız olur.
AaronLS

1
MS-Access, JOIN deyimi ile farklı bir UPDATE kullanır. Şuna bir göz atın: sql-und-xml.de/sql-tutorial/…
Christian Ammer

92
Bu mssql için iyi görünüyor ama mysql çalışmıyor gibi görünüyor. Gerçi işi yapmak gibi görünüyor: UPDATE Sales_Import, RetrieveAccountNumber SET Sales_Import.AccountNumber = RetrieveAccountNumber.AccountNumber where Sales_Import.LeadID = RetrieveAccountNumber.LeadID;. Biraz konu dışı ama yardımcı olabilir
Edd

7
İç birleşmeye gerek olmadığını düşünüyorum. İşlerin altına Vonki çözümü: GÜNCELLEME [Sales_Lead] [Dbo] [Sales_Import] SET [AccountNumber] = RetrieveAccountNumber.AccountNumber RetrieveAccountNumber WHERE [Sales_Lead] [Dbo] [Sales_Import] .LeadID = RetrieveAccountNumber.LeadID....
Gutti

289

İçeriği bir tablodan diğerine kopyalamanın basit yolu aşağıdaki gibidir:

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

Belirli verilerin kopyalanmasını sağlamak için koşul da ekleyebilirsiniz.


2
Bu çalışır, ancak UPDATE tablo2 SET FROM table2.col1 = table1.col1, table2.col2 = table1.col2, ... table2 WHERE table1.memberid = table2.memberid
Sirentec

2
Bu işe yaramadı, ancak UPDATE table2, table1 SET table2.col1 = table1.col1, ... NEREDE table1.memberid = table2.memberid (mysql ve phpmyadmin)
Tom Kuschel

156

SQL Server 2008 + MERGEiçin Tescilli UPDATE ... FROMsözdizimi kullanmak bazı çekiciliğe sahiptir.

Standart SQL ve dolayısıyla daha portatif olmasının yanı sıra, nihai sonucun belirsiz olması yerine kaynak tarafında birden fazla birleştirilmiş satır (ve böylece güncellemede kullanılacak birden fazla olası farklı değer) olması durumunda da bir hata oluşturacaktır. .

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

Ne yazık ki, hangisinin kullanılacağı tamamen tercih edilen stile gelmeyebilir. MERGESQL Server'da uygulanması çeşitli hatalardan etkilenmiştir. Aaron Bertrand bildirilenlerin bir listesini burada derledi .


11
Dikkat MERGE!
Jakub Januszkiewicz

2
Birleştirme sözdizimini hiç bilmiyordum. Update + Join'den çok daha temiz.
Tony Ashworth

SQL Server uygulamasının raporlanması için +1
AF

1
MERGE'i kullanmak için argümanlar ( yukarıda bağlantılı sqlblog.com'dan gelenler dahil ) zorlayıcı olabilir, ancak dikkate alınması gereken bir şey, MSDN'ye göre şu olabilir : ... MERGE ifadesi, iki tabloda karmaşık bir karışım olduğunda en iyi şekilde çalışır eşleşen özellikler ... Bir tabloyu başka bir tablonun satırlarına göre güncellerken, temel INSERT, UPDATE ve DELETE ifadeleri ile gelişmiş performans ve ölçeklenebilirlik elde edilebilir
Tony Pulokas 27:16

1
@ jkp1187 Bu soru SQL Server olarak etiketlenmiştir. Yani RE: FWIW - yaklaşık sıfır.
Martin Smith

104

Gelecekteki geliştiriciler için genel cevap.

SQL Server

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

Oracle (ve 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
En azından SQL Server için not, üst güncelleme yan tümcesinde ( update t1...yerine update Table1...) tablo adı yerine takma ad kullanın
gordon

2
Oracle sürümü çalışmıyor. ORA-00933
Ka3ak

35

PostgreSQL için:

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

34

MSSQL kullandığınız anlaşılıyor, o zaman, doğru hatırlıyorsam, böyle yapılır:

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

33

Ben eşleşen bir anahtar vardı satırları için foo.newayarlanmış aynı sorun vardı . Oracle'da böyle bir şey yaptım:nullfoobar

foo güncelle
set foo.new = (bar.new'i seçin
                  bardan 
                  burada foo.key = bar.key)
varsa (1'i seçin
              bardan
              burada foo.key = bar.key)

4
Neden olduğu NEREDE OLMADIĞI gerekli?
Georg Schölly

6
Çünkü foo'daki her satırın barda eşleşme olmaması null olur, çünkü select deyimi null üretir. Umarım bu benim açıklamaya yönelik ilk girişimimden daha açıktı.
Kjell Andreassen

aşağıdaki yanıtı kontrol edin stackoverflow.com/questions/224732/…
Basheer AL-MOMANI

@KjellAndreassen Sorunumu çözdün. Kodun için teşekkürler.
Bhavin Thummar

27

İyi çalışan MySql için:

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

26

SQL Server'da benim için işe yarayanlar:

UPDATE [AspNetUsers] SET

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

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

18

Yanıtlar için teşekkürler. Bir çözüm buldum 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)  

17
Buradaki kodun işe yarayıp yaramadığı, muhtemelen yayınlanan diğer iki çözüme bakmalısınız. Çok daha net ve hataya daha az eğilimli ve neredeyse kesinlikle daha hızlı.
Tom H

3
Bu çözüm hakkında sadece bir not olan UPDATE ... FROM tescillidir, bu nedenle, SQL 2005 veya önceki bir sürümünü kullandığınız için MERGE deyimini kullanamazsanız, MSSQL'de bir tablo kaynağıyla güncellemeler gerçekleştirmek için ANSI uyumlu bir yöntemdir. Kaynak: sqlblog.com/blogs/hugo_kornelis/archive/2008/03/10/…
sözde

1
benim için çalışan tek çözüm çünkü onun standart bir SQL güncelleme deyimi (UPDATE SET NEREDE), çok teşekkürler
Basheer AL-MOMANI

13

Tabloların farklı veritabanlarında olması durumunda. (MSSQL)

update database1..Ciudad
set CiudadDistrito=c2.CiudadDistrito

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

10

Tablo1'i kimliğe dayalı olarak Table2 ile güncelleştirmek için aşağıdaki sorgu bloğunu kullanın:

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

Bu sorunu çözmenin en kolay yolu budur .


8

MS Kare

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  ;

3

aynı tablo içinde güncelleme:

  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

Aşağıdaki SQL biri önerdi, SQL Server'da çalışmaz. Bu sözdizimi bana eski okul sınıfımı hatırlatıyor:

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

NOT INVeya kullanan diğer tüm sorgular NOT EXISTSönerilmez. NULL'lar, OP'nin tüm veri kümesini daha küçük bir alt kümeyle karşılaştırdığı için ortaya çıkar, elbette eşleşen bir sorun olacaktır. Bu JOIN, kullanarak kaçmak sorunu yerine doğru SQL yazarak düzeltilmelidir NOT IN. Bu durumda NOT INveya tuşunu kullanarak başka sorunlarla karşılaşabilirsiniz NOT EXISTS.

SQL Server'da katılarak başka bir tabloya dayalı bir tabloyu güncellemenin geleneksel yolu olan en üstteki oyum. Dediğim gibi, UPDATESQL Server'da ilk olarak katılmadıkça iki tabloyu aynı ifadede kullanamazsınız.


2
Sadece SQL Server 2017'de bunun mükemmel bir şekilde çalıştığını söyleyebilirim. Gelecekteki insanlar için bir not gibi. Onlara katılmanıza gerek yok.
SharpShade

3

postgresql ile çalışır

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

Bunun basit bir örnek olduğunu düşündüm, biri daha kolay olabilir,

        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

Oracle 11g

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

-1

Bu, bir tabloyu başka bir tabloda bulunmayan sütun değerine göre güncellemenizi sağlar.

    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
    )

Bu, her iki tabloda bulunan sütun değerine dayalı olarak bir tabloyu güncelleştirir.

    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

bunu dene :

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

Bir şey daha eklemek istiyorum.

Aynı değere sahip bir değeri güncellemeyin, fazladan günlüğe kaydetme ve gereksiz ek yük oluşturur. Aşağıdaki örneğe bakın - 3'e bağlanmasına rağmen güncellemeyi yalnızca 2 kayıtta gerçekleştirir.

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

Yukarıdaki cevaplar sizin için çalışmıyorsa bunu deneyin

Update Sales_Import A left join RetrieveAccountNumber B on A.LeadID = B.LeadID
Set A.AccountNumber = B.AccountNumber
where A.LeadID = B.LeadID 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.