ChatGPT解决这个技术问题 Extra ChatGPT

使用连接的 SQL 更新查询

我必须使用由 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

我想用在上述条件中加入的其他值来更新表 item_mastermf_item_number 字段值。

如何在 MS SQL Server 中执行此操作?

请停止使用那些隐含的连接开始。这是一种糟糕的技术,由于意外的交叉连接而导致不正确的结果。此代码样式已过时 18 年
另请参阅 SO 问题... stackoverflow.com/questions/1293330/…

C
Community
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 ...

仅供参考,这在 MySQL 中不起作用(不同的语法)!对于 MySQL,请查看 gcbenison 的答案
@Sliq 谢谢。无论如何,这不是 MySQL 问题。
F
Florent

将此调整到 MySQL —— UPDATE 中没有 FROM 子句,但这有效:

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

R
Remus Rusanu

最简单的方法之一是使用公用表表达式(因为您已经使用 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>

查询执行引擎将自行确定如何更新记录。


太好了,CTE 的使用使得将原始 SELECT 转换为 UPDATE 变得简单
只要您的 SELECT 查询没有任何聚合、DISTINCT 等,就可以工作。
我通常以分号开头来终止先前的语句(如果有的话)。 CTE 摇滚!简单设计复杂的查询/连接更新。我用它所有的时间...
S
Suraj Shrestha

上面没有使用您的 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%'

m
marc_s

您可以使用 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 子句中,您需要提供将这些表绑定在一起的条件和连接操作。

马克


..或在 FROM 子句中使用 ANSI JOINS
是的,请使用 ansi 连接,如果您不小心得到了交叉连接,您可能会在更新中遇到真正的麻烦。
P
Prashant Pimpale

MySQL:通常,根据您的要求进行必要的更改:

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

这不是 MySQL 问题
J
JH_

试试这样...

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;

这甚至在语法上都不正确,而更早接受的答案不仅在语法上正确,而且解决了所提出的确切问题。
M
MBT

您可以使用以下查询:

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`

v
vishwampandya

在 SQL 中使用连接查询进行更新非常简单。无需 使用 FROM 子句即可。这是一个例子:

    UPDATE customer_table c 

      JOIN  
          employee_table e
          ON c.city_id = e.city_id  
      JOIN 
          anyother_ table a
          ON a.someID = e.someID

    SET c.active = "Yes"

    WHERE c.city = "New york";

B
Bhadresh Patel

如果您使用的是 SQL Server,您可以从另一个表更新一个表,而无需指定连接,只需从 where 子句链接这两个表。这使得 SQL 查询更加简单:

 UPDATE Table1
    SET Table1.col1 = Table2.col1,
        Table1.col2 = Table2.col2
    FROM
        Table2
    WHERE
        Table1.id = Table2.id

Y
Yashar Aliabbasi

您可以使用 MERGE 命令更新对 MATCHEDNOT 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

不是,我很确定,在 SQL Server 2005 中,问题被标记为,但这是现代 SQL Server 版本的最佳(即更标准)方式
F
FFFffff

让我在所有现有答案中添加一个警告:

使用 SELECT ... FROM 语法时,您应该记住它是 T-SQL 的专有语法并且是不确定的。最糟糕的是,您没有收到任何警告或错误,它只是顺利执行。

documentation 中有完整的示例说明:

指定 FROM 子句以提供更新操作的条件时要小心。如果 UPDATE 语句包含未指定的 FROM 子句,则该语句的结果是未定义的,即,如果 UPDATE 语句不是确定性的,则每个更新的列出现只有一个值可用。


D
Darrel Lee

我一直在尝试做这样的事情,我突然想到尝试使用以下语法(使用元组)

update dstTable T
set (T.field1, T.field2, T.field3) = 
       (select S.value1, S.value2, S.value3
        from srcTable S
         where S.key = T.Key);

令人惊讶的是,它奏效了。我正在使用 Oracle(我认为是 12c)。这个标准 SQL 或 Oracle 是特定的吗?

注意:在我的示例中,我正在更新整个表格(填充新列)。更新没有 where 子句,因此所有行都将被更新。当子查询不返回行时,您的字段将设置为 NULL。 (并且它不能返回超过一行)。