Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Sql Server中使用子查询更新查询_Sql_Sql Server_Tsql_Sql Update - Fatal编程技术网

在Sql Server中使用子查询更新查询

在Sql Server中使用子查询更新查询,sql,sql-server,tsql,sql-update,Sql,Sql Server,Tsql,Sql Update,我有这样一个简单的表结构: 表tempData ╔══════════╦═══════╗ ║ NAME ║ MARKS ║ ╠══════════╬═══════╣ ║ Narendra ║ 80 ║ ║ Ravi ║ 85 ║ ║ Sanjay ║ 90 ║ ╚══════════╩═══════╝ 我还有另一个表名为tempDataView,如下所示 ╔══════════╦═══════╗ ║ NAME ║ MARKS ║ ╠════════

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

tempData

╔══════════╦═══════╗
║   NAME   ║ MARKS ║
╠══════════╬═══════╣
║ Narendra ║    80 ║
║ Ravi     ║    85 ║
║ Sanjay   ║    90 ║
╚══════════╩═══════╝
我还有另一个表名为tempDataView,如下所示

╔══════════╦═══════╗
║   NAME   ║ MARKS ║
╠══════════╬═══════╣
║ Narendra ║       ║
║ Narendra ║       ║
║ Narendra ║       ║
║ Narendra ║       ║
║ Ravi     ║       ║
║ Ravi     ║       ║
║ Sanjay   ║       ║
╚══════════╩═══════╝
我想更新表tempDataView,方法是根据tempDataView-NametempData-Name相比设置标记

是的,让我向您展示我尝试过的,我尝试使用光标来解决这个问题,它的解决非常完美,但我正在找到使用子查询来解决它的方法

这是:

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

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

即使在
UPDATE
语句中,您也可以联接这两个表

UPDATE  a
SET     a.marks = b.marks
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name
为了提高性能,请在两个表的列
标记上定义
索引

使用
子查询

UPDATE  tempDataView 
SET     marks = 
        (
          SELECT marks 
          FROM tempData b 
          WHERE tempDataView.Name = b.Name
        )

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

SELECT *
FROM    tempDataView a
        INNER JOIN tempData b
            ON a.Name = b.Name
然后请注意,我们有两个表别名
a
b
。使用这些别名,您可以轻松地生成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 FIDLE作为一个游戏

此线程的标题询问如何在更新中使用子查询。下面是一个例子:

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
用一些例子很好地解释了更新操作。虽然它是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\u id条目不匹配,则第一个查询会将相应的名称字段设置为NULL,而第二个查询根本不会更新该行

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

UPDATE tempDataView SET (marks) =
    (SELECT marks FROM tempData
     WHERE tempDataView.Name = tempData.Name);

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

UPDATE
    A
SET
    A.ValueToChange = B.NewValue
FROM
    (
        Select * From C
    ) B
Where 
    A.Id = B.Id

是的。但是请建议我使用子查询的任何方法。用
subquery
更新答案,但是我宁愿使用
JOIN
而不是
subquery
。为什么要在
标记
列上定义
索引
?它是否应该位于
Name
列上?出现错误:子查询返回的值超过1。当子查询在=、!=、=或者当子查询用作表达式时。请单独尝试子查询并调整它,直到只得到1个结果。可能将
SELECT
更改为
selecttop1
这是正确的学习方法+1用于显示学习方法。谢谢我不确定这将如何编译,计数(*)没有分组依据来知道要计数什么。@paqogomez只需在任何有记录的表上尝试一下即可。e、 g。从EventLog中选择count(*),其中year=2018,这样您就可以简单地计算整个表。我支持我的反对票,这与您的特权问题(无论标题如何)无关,但此线程的标题是“使用子查询更新查询”,我的示例不言而喻地做到了这一点。仅供参考,我不是在计算“整个表”-count(*)后面跟着一个“where”子句-因此它是在计算满足“where”条件的行。不幸的是,第一个表单在MS SQL server中不起作用。谢谢您的回答!为了帮助其他人阅读本文,您是否可以快速添加一个解释,说明为什么此代码可以解决此问题?