92

我有一个像这样的简单表结构:

tempData

╔══════════╦═══════╗
║   NAME   ║ MARKS ║
╠══════════╬═══════╣
║ Narendra ║    80 ║
║ Ravi     ║    85 ║
║ Sanjay   ║    90 ║
╚══════════╩═══════╝

而且我还有另一个表名像这样的tempDataView

╔══════════╦═══════╗
║   NAME   ║ MARKS ║
╠══════════╬═══════╣
║ Narendra ║       ║
║ Narendra ║       ║
║ Narendra ║       ║
║ Narendra ║       ║
║ Ravi     ║       ║
║ Ravi     ║       ║
║ Sanjay   ║       ║
╚══════════╩═══════╝

我想更新表tempDataView,通过 根据tempDataView - NametempData - Name相比设置标记

是的,让我向您展示我的尝试,我尝试使用 Cursor 解决这个问题,并且完美解决,但我正在寻找使用Subquery解决它的方法

这里是:

Declare @name varchar(50),@marks varchar(50)
Declare @cursorInsert CURSOR
set @cursorInsert = CURSOR FOR
Select name,marks from tempData
OPEN @cursorInsert
FETCH NEXT FROM @cursorInsert
into @name,@marks
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE tempDataView set marks = @marks where name = @name
FETCH NEXT FROM @cursorInsert
INTO @name,@marks
END
CLOSE @cursorInsert
DEALLOCATE @cursorInsert

实际上,使用子查询解决它就像我的作业一样。

4

5 回答 5

201

您甚至可以在UPDATE语句上加入两个表,

UPDATE  a
SET     a.marks = b.marks
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

为了获得更快的性能,请在两个表上定义一个INDEXon 列。marks

使用SUBQUERY

UPDATE  tempDataView 
SET     marks = 
        (
          SELECT marks 
          FROM tempData b 
          WHERE tempDataView.Name = b.Name
        )
于 2013-01-31T04:52:01.197 回答
39

因为您刚刚学习,我建议您练习将 SELECT 连接转换为 UPDATE 或 DELETE 连接。首先,我建议您生成一个连接这两个表的 SELECT 语句:

SELECT *
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

然后注意我们有两个表别名ab. 使用这些别名,您可以轻松地生成 UPDATE 语句来更新表 a 或 b。对于表 a,您有 JW 提供的答案。如果要更新b,语句将是:

UPDATE  b
SET     b.marks = a.marks
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

现在,要将语句转换为 DELETE 语句,请使用相同的方法。下面的语句将只删除a那些按名称匹配的记录(保持 b 不变):

DELETE a
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name

您可以将 JW 创建的 SQL Fiddle 用作游乐场

于 2013-01-31T05:00:12.100 回答
9

在我的示例中,我找到了解决方案,因为我在更新和子查询方面遇到了同样的问题:

UPDATE
    A
SET
    A.ValueToChange = B.NewValue
FROM
    (
        Select * From C
    ) B
Where 
    A.Id = B.Id
于 2020-02-12T19:01:10.300 回答
0

该主题的标题询问如何在更新中使用子查询。这是一个例子:

update [dbName].[dbo].[MyTable] 
set MyColumn = 1 
where 
    (
        select count(*) 
        from [dbName].[dbo].[MyTable] mt2 
        where
            mt2.ID > [dbName].[dbo].[MyTable].ID
            and mt2.Category = [dbName].[dbo].[MyTable].Category
    ) > 0
于 2017-09-21T10:21:44.183 回答
0

是更新操作的一个很好的解释,并带有一些示例。虽然它是 Postgres 站点,但 SQL 查询对其他数据库也有效。以下示例直观易懂。

-- Update contact names in an accounts table to match the currently assigned salesmen:

UPDATE accounts SET (contact_first_name, contact_last_name) =
    (SELECT first_name, last_name FROM salesmen
     WHERE salesmen.id = accounts.sales_id);

-- A similar result could be accomplished with a join:

UPDATE accounts SET contact_first_name = first_name,
                    contact_last_name = last_name
  FROM salesmen WHERE salesmen.id = accounts.sales_id;

但是,如果 salesmen.id 不是唯一键,则第二个查询可能会给出意外结果,而如果有多个 id 匹配,则第一个查询保证会引发错误。此外,如果没有匹配特定的 accounts.sales_id 条目,第一个查询会将相应的名称字段设置为 NULL,而第二个查询根本不会更新该行。

因此,对于给定的示例,最可靠的查询如下所示。

UPDATE tempDataView SET (marks) =
    (SELECT marks FROM tempData
     WHERE tempDataView.Name = tempData.Name);
于 2018-08-03T16:04:54.333 回答