Permintaan pembaruan SQL menggunakan gabungan

664

Saya harus memperbarui bidang dengan nilai yang dikembalikan oleh gabungan 3 tabel.

Contoh:

select
    im.itemid
    ,im.sku as iSku
    ,gm.SKU as GSKU
    ,mm.ManufacturerId as ManuId
    ,mm.ManufacturerName
    ,im.mf_item_number
    ,mm.ManufacturerID
from 
    item_master im, group_master gm, Manufacturer_Master mm 
where
    im.mf_item_number like 'STA%'
    and im.sku=gm.sku
    and gm.ManufacturerID = mm.ManufacturerID
    and gm.manufacturerID=34

Saya ingin memperbarui nilai mf_item_numberbidang tabel item_masterdengan beberapa nilai lain yang tergabung dalam kondisi di atas.

Bagaimana saya bisa melakukan ini di MS SQL Server?

Shyju
sumber
124
Harap hentikan penggunaan gabungan tersirat tersebut untuk memulai. Ini adalah teknik yang buruk yang mengarah ke hasil yang salah karena gabungan silang yang tidak terduga. Gaya kode ini 18 tahun kedaluwarsa
HLGEM
2
Lihat juga pertanyaan SO ... stackoverflow.com/questions/1293330/…
SteveC

Jawaban:

1251
UPDATE im
SET mf_item_number = gm.SKU --etc
FROM item_master im
JOIN group_master gm
    ON im.sku = gm.sku 
JOIN Manufacturer_Master mm
    ON gm.ManufacturerID = mm.ManufacturerID
WHERE im.mf_item_number like 'STA%' AND
      gm.manufacturerID = 34

Untuk memperjelasnya ... UPDATEKlausa dapat merujuk ke tabel alias yang ditentukan dalam FROMklausa. Jadi imdalam hal ini valid

Contoh umum

UPDATE A
SET foo = B.bar
FROM TableA A
JOIN TableB B
    ON A.col1 = B.colx
WHERE ...
gbn
sumber
9
Postgres mengeluhkan UPDATE im; im adalah alias yang Postgres tidak kenali: /
fatuhoku
10
FYI ini TIDAK akan bekerja di MySQL (sintaks berbeda)! Untuk MySQL, lihat jawaban gcbenison
Sliq
67

Salah satu cara termudah adalah dengan menggunakan ekspresi tabel umum (karena Anda sudah menggunakan SQL 2005):

with cte as (
select
    im.itemid
    ,im.sku as iSku
    ,gm.SKU as GSKU
    ,mm.ManufacturerId as ManuId
    ,mm.ManufacturerName
    ,im.mf_item_number
    ,mm.ManufacturerID
    , <your other field>
from 
    item_master im, group_master gm, Manufacturer_Master mm 
where
    im.mf_item_number like 'STA%'
    and im.sku=gm.sku
    and gm.ManufacturerID = mm.ManufacturerID
    and gm.manufacturerID=34)
update cte set mf_item_number = <your other field>

Mesin eksekusi kueri akan mencari tahu sendiri cara memperbarui catatan.

Remus Rusanu
sumber
8
Luar biasa, penggunaan CTE membuatnya mudah untuk mengubah SELECT asli menjadi UPDATE
SteveC
4
Berfungsi selama permintaan SELECT Anda tidak memiliki agregat,
PUTUS
1
Saya biasanya mulai dengan titik koma untuk mengakhiri pernyataan sebelumnya (jika ada). Batu CTE! Sederhana untuk mendesain permintaan yang rumit / pembaruan yang digabungkan. Saya menggunakannya sepanjang waktu ...
Adam W
64

Mengadaptasi ini ke MySQL - tidak ada FROMklausa UPDATE, tetapi ini berfungsi:

UPDATE
    item_master im
    JOIN
    group_master gm ON im.sku=gm.sku 
    JOIN
    Manufacturer_Master mm ON gm.ManufacturerID=mm.ManufacturerID
SET
    im.mf_item_number = gm.SKU --etc
WHERE
    im.mf_item_number like 'STA%'
    AND
    gm.manufacturerID=34
gcbenison
sumber
12

Tidak menggunakan sql Anda di atas tetapi di sini adalah contoh memperbarui tabel berdasarkan pernyataan bergabung.

UPDATE p
SET    p.category = c.category
FROM   products p
       INNER JOIN prodductcatagories pg
            ON  p.productid = pg.productid
       INNER JOIN categories c
            ON  pg.categoryid = c.cateogryid
WHERE  c.categories LIKE 'whole%'
Gratzy
sumber
8

Anda bisa menentukan tabel tambahan yang digunakan dalam menentukan bagaimana dan apa yang akan diperbarui dengan klausa "FROM" dalam pernyataan UPDATE, seperti ini:

update item_master
set mf_item_number = (some value)
from 
   group_master as gm
   join Manufacturar_Master as mm ON ........
where
 .... (your conditions here)

Di klausa WHERE, Anda harus menyediakan ketentuan dan bergabung dengan operasi untuk mengikat tabel ini bersama-sama.

Marc

marc_s
sumber
5
..atau gunakan ANSI GABUNG dalam klausa FROM
gbn
5
Ya, silakan gunakan ansi joins, Anda bisa berada dalam masalah besar dalam pembaruan jika Anda secara tidak sengaja mendapat umpan silang.
HLGEM
7

MySQL: Secara umum, lakukan perubahan yang diperlukan sesuai kebutuhan Anda:

UPDATE
    shopping_cart sc
    LEFT JOIN
    package pc ON sc. package_id = pc.id    
SET
    sc. amount = pc.amount
Vinod Joshi
sumber
3

Coba seperti ini ...

Update t1.Column1 = value 
from tbltemp as t1 
inner join tblUser as t2 on t2.ID = t1.UserID 
where t1.[column1]=value and t2.[Column1] = value;
Ankitkumar Tandel
sumber
2

Anda dapat menggunakan kueri berikut:

UPDATE im
SET mf_item_number = (some value) 
FROM item_master im
JOIN group_master gm
    ON im.sku = gm.sku 
JOIN Manufacturer_Master mm
    ON gm.ManufacturerID = mm.ManufacturerID
WHERE im.mf_item_number like 'STA%' AND
      gm.manufacturerID = 34    `sql`
Prasan Karunarathna
sumber
1

Anda dapat memperbarui dengan MERGECommand dengan kontrol lebih besar MATCHEDdan NOT MATCHED: (Saya sedikit mengubah kode sumber untuk menunjukkan maksud saya)

USE tempdb;
GO
IF(OBJECT_ID('target') > 0)DROP TABLE dbo.target
IF(OBJECT_ID('source') > 0)DROP TABLE dbo.source
CREATE TABLE dbo.Target
    (
      EmployeeID INT ,
      EmployeeName VARCHAR(100) ,
      CONSTRAINT Target_PK PRIMARY KEY ( EmployeeID )
    );
CREATE TABLE dbo.Source
    (
      EmployeeID INT ,
      EmployeeName VARCHAR(100) ,
      CONSTRAINT Source_PK PRIMARY KEY ( EmployeeID )
    );
GO
INSERT  dbo.Target
        ( EmployeeID, EmployeeName )
VALUES  ( 100, 'Mary' );
INSERT  dbo.Target
        ( EmployeeID, EmployeeName )
VALUES  ( 101, 'Sara' );
INSERT  dbo.Target
        ( EmployeeID, EmployeeName )
VALUES  ( 102, 'Stefano' );

GO
INSERT  dbo.Source
        ( EmployeeID, EmployeeName )
VALUES  ( 100, 'Bob' );
INSERT  dbo.Source
        ( EmployeeID, EmployeeName )
VALUES  ( 104, 'Steve' );
GO

SELECT * FROM dbo.Source
SELECT * FROM dbo.Target

MERGE Target AS T
USING Source AS S
ON ( T.EmployeeID = S.EmployeeID )
WHEN MATCHED THEN
    UPDATE SET T.EmployeeName = S.EmployeeName + '[Updated]';
GO 
SELECT '-------After Merge----------'
SELECT * FROM dbo.Source
SELECT * FROM dbo.Target
Yashar Aliabbasi
sumber