เคียวรีอัพเดต SQL โดยใช้การรวม


664

ฉันต้องอัปเดตฟิลด์ด้วยค่าที่ส่งคืนโดยการเข้าร่วม 3 ตาราง

ตัวอย่าง:

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

ฉันต้องการอัปเดตmf_item_numberค่าฟิลด์ของตารางitem_masterด้วยค่าอื่น ๆ ซึ่งเข้าร่วมในเงื่อนไขข้างต้น

ฉันจะทำสิ่งนี้ใน MS SQL Server ได้อย่างไร


124
โปรดหยุดใช้การเชื่อมต่อโดยนัยเหล่านั้นเพื่อเริ่มต้น มันเป็นเทคนิคที่ไม่ดีที่นำไปสู่ผลลัพธ์ที่ไม่ถูกต้องเนื่องจากการรวมข้ามที่ไม่คาดคิด รูปแบบโค้ดนี้มีอายุ 18 ปี
HLGEM

2
ดูเพิ่มเติมดังนั้นคำถาม ... stackoverflow.com/questions/1293330/…
SteveC

คำตอบ:


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

เพื่อให้ชัดเจน ... UPDATEประโยคสามารถอ้างถึงนามแฝงของตารางที่ระบุไว้ในFROMข้อ ดังนั้นimในกรณีนี้ถูกต้อง

ตัวอย่างทั่วไป

UPDATE A
SET foo = B.bar
FROM TableA A
JOIN TableB B
    ON A.col1 = B.colx
WHERE ...

9
Postgres บ่นเกี่ยวกับUPDATE im; im เป็นนามแฝงที่ Postgres ไม่รู้จัก: /
fatuhoku

10
FYIสิ่งนี้จะไม่ทำงานใน MySQL (ไวยากรณ์ต่างกัน)! สำหรับ MySQL ลองดูที่คำตอบของ
gcbenison

67

หนึ่งในวิธีที่ง่ายที่สุดคือการใช้นิพจน์ตารางทั่วไป (เนื่องจากคุณอยู่ใน 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>

เอ็นจิ้นประมวลผลคิวรีจะค้นหาวิธีปรับปรุงระเบียน


8
ยอดเยี่ยมการใช้ CTE ทำให้ง่ายต่อการแปลง SELECT ดั้งเดิมให้เป็น UPDATE
SteveC

4
ทำงานได้ตราบใดที่การสืบค้น SELECT ของคุณไม่มีการรวม DISTINCT และอื่น ๆ
Baodad

1
ฉันมักจะเริ่มต้นด้วยเครื่องหมายอัฒภาคเพื่อยกเลิกคำสั่งก่อนหน้า (ถ้ามี) หิน CTE! ง่ายต่อการออกแบบแบบสอบถามที่ซับซ้อน / ปรับปรุงเข้าร่วม ฉันใช้มันตลอดเวลา ...
อดัม W

64

ปรับตัวเข้ากับ MySQL - ไม่มีFROMส่วนคำสั่งUPDATEแต่ใช้งานได้:

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

12

ไม่ได้ใช้ sql ของคุณด้านบน แต่นี่คือตัวอย่างของการอัพเดตตารางตามคำสั่ง join

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%'

8

คุณสามารถระบุตารางเพิ่มเติมที่ใช้ในการกำหนดวิธีการและสิ่งที่จะอัปเดตด้วยคำสั่ง "FROM" ในคำสั่ง UPDATE เช่นนี้:

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

ในส่วนคำสั่ง WHERE คุณจะต้องระบุเงื่อนไขและเข้าร่วมการดำเนินการเพื่อผูกตารางเหล่านี้เข้าด้วยกัน

มาร์ค


5
.. หรือใช้ ANSI JOINS ในส่วนคำสั่ง
gbn

5
ใช่โปรดใช้การรวม ansi คุณอาจประสบปัญหาจริงในการอัปเดตหากคุณบังเอิญเข้าร่วมไขว้
HLGEM

7

MySQL: โดยทั่วไปทำการเปลี่ยนแปลงที่จำเป็นตามความต้องการของคุณ:

UPDATE
    shopping_cart sc
    LEFT JOIN
    package pc ON sc. package_id = pc.id    
SET
    sc. amount = pc.amount


2

คุณสามารถใช้แบบสอบถามต่อไปนี้:

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`

1

คุณสามารถอัปเดตด้วยMERGEคำสั่งที่ควบคุมได้มากขึ้นMATCHEDและNOT MATCHED: (ฉันเปลี่ยนรหัสต้นฉบับเล็กน้อยเพื่อแสดงจุดของฉัน)

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.