結合を使用した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 2010

2
SO質問...も参照してください。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
ちなみに、これはMySQLでは動作しません(異なる構文)!MySQLの場合、gcbenisonの答えを確認してください
Sliq

67

最も簡単な方法の1つは、共通のテーブル式を使用することです(既に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に適合させる-ありません FROMUPDATEが、これは機能します。

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を使用しませんでしたが、ここでは、結合ステートメントに基づいてテーブルを更新する例を示します。

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

次のように、UPDATEステートメントの「FROM」句を使用して、更新方法と更新対象を決定するために使用する追加のテーブルを指定できます。

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
..or使用ANSIは、FROM句内の結合
GBN

5
はい、ANSI結合を使用してください。誤ってクロス結合を取得した場合、更新で実際に問題が発生する可能性があります。
HLGEM 2009年

7

MySQL:一般に、要件に合わせて必要な変更を行います。

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

3

このようにしてみてください...

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

次のクエリを使用できます。

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.