Запит на оновлення 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
Дивіться також 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
Постгрес скаржиться на 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 в ОНОВЛЕННЯ
SteveC

4
Працює до тих пір, поки у вашому SELECT запиті немає агрегатів, DISTINCT тощо.
Baodad

1
Зазвичай я починаю з крапки з комою, щоб припинити попереднє твердження (якщо воно є). CTE скелі! Просте проектування складних запитів / оновлених оновлень. Я використовую його весь час ...
Adam 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 вище, але ось приклад оновлення таблиці на основі заяви.

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, як це:

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 у пункті FROM
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

Ви можете оновити з MERGECommand з набагато більшим контролем над 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.