Truy vấn cập nhật SQL bằng cách sử dụng các phép nối


663

Tôi phải cập nhật một trường có giá trị được trả về bằng cách nối 3 bảng.

Thí dụ:

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

Tôi muốn cập nhật các mf_item_numbergiá trị trường của bảng item_mastervới một số giá trị khác được nối trong điều kiện trên.

Làm thế nào tôi có thể làm điều này trong MS SQL Server?


124
Hãy ngừng sử dụng những liên kết ngụ ý để bắt đầu. Đó là một kỹ thuật kém dẫn đến kết quả không chính xác do tham gia chéo bất ngờ. Kiểu mã này đã hết hạn 18 năm
HLGEM

2
Xem thêm câu hỏi SO ... stackoverflow.com/questions/1293330/
Kẻ

Câu trả lời:


1250
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

Để làm cho nó rõ ràng ... UPDATEMệnh đề có thể tham chiếu một bí danh bảng được chỉ định trong FROMmệnh đề. Vì vậy, imtrong trường hợp này là hợp lệ

Ví dụ chung

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

9
Postgres phàn nàn về UPDATE im; tôi là một bí danh mà Postgres không nhận ra: /
fatuhoku

10
FYI này sẽ KHÔNG hoạt động trong MySQL (cú pháp khác nhau)! Đối với MySQL, hãy xem câu trả lời của
gcbenison

67

Một trong những cách dễ nhất là sử dụng biểu thức bảng chung (vì bạn đã có trên 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>

Công cụ thực thi truy vấn sẽ tự tìm ra cách cập nhật bản ghi.


8
Tuyệt vời, việc sử dụng CTE giúp đơn giản để chuyển đổi CHỌN ban đầu thành CẬP NHẬT
SteveC

4
Hoạt động miễn là truy vấn CHỌN của bạn không có bất kỳ tập hợp, DISTINCT, v.v.
Baodad

1
Tôi thường bắt đầu bằng dấu chấm phẩy để chấm dứt tuyên bố trước đó (nếu có). CTE đá! Đơn giản để thiết kế các bản cập nhật truy vấn / tham gia phức tạp. Tôi sử dụng nó mọi lúc ...
Adam W

64

Thích ứng điều này với MySQL - không có FROMđiều khoản nào UPDATE, nhưng điều này hoạt động:

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

Không sử dụng sql của bạn ở trên nhưng đây là một ví dụ về việc cập nhật bảng dựa trên câu lệnh nối.

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

Bạn có thể chỉ định các bảng bổ sung được sử dụng để xác định cách thức và nội dung cần cập nhật với mệnh đề "TỪ" trong câu lệnh CẬP NHẬT, như sau:

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

Trong mệnh đề WHERE, bạn cần cung cấp các điều kiện và nối các hoạt động để liên kết các bảng này lại với nhau.

Marc


5
.. hoặc sử dụng ANSI THAM GIA trong mệnh đề TỪ
gbn

5
Có, vui lòng sử dụng ansi tham gia, bạn có thể gặp rắc rối thực sự trong một bản cập nhật nếu bạn vô tình có một tham gia chéo.
HLGEM

7

MySQL: Nói chung, thực hiện các thay đổi cần thiết theo yêu cầu của bạn:

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

3

Hãy thử như thế này ...

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;

2

Bạn có thể sử dụng truy vấn sau:

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

Bạn có thể cập nhật với MERGECommand với nhiều quyền kiểm soát hơn MATCHEDNOT MATCHED: (Tôi đã thay đổi một chút mã nguồn để chứng minh quan điểm của mình)

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.