首页 文章

如何从SQL Server中的SELECT更新?

提问于
浏览
3179

SQL Server 中,可以使用 SELECT 语句将 insert 放入表中:

INSERT INTO Table (col1, col2, col3)
SELECT col1, col2, col3 
FROM other_table 
WHERE sql = 'cool'

是否也可以通过 SELECT 进行更新?我有一个包含值的临时表,并希望使用这些值更新另一个表 . 也许是这样的:

UPDATE Table SET col1, col2
SELECT col1, col2 
FROM other_table 
WHERE sql = 'cool'
WHERE Table.id = other_table.id

30 回答

  • 45
    UPDATE table 
    SET Col1 = i.Col1, 
        Col2 = i.Col2 
    FROM (
        SELECT ID, Col1, Col2 
        FROM other_table) i
    WHERE 
        i.ID = table.ID
    
  • 0

    简单的方法是:

    UPDATE
        table_to_update,
        table_info
    SET
        table_to_update.col1 = table_info.col1,
        table_to_update.col2 = table_info.col2
    
    WHERE
        table_to_update.ID = table_info.ID
    
  • 692

    以下示例使用派生表(FROM子句后面的SELECT语句)返回旧值和新值以进行进一步更新:

    UPDATE x
    SET    x.col1 = x.newCol1,
           x.col2 = x.newCol2
    FROM   (SELECT t.col1,
                   t2.col1 AS newCol1,
                   t.col2,
                   t2.col2 AS newCol2
            FROM   [table] t
                   JOIN other_table t2
                     ON t.ID = t2.ID) x
    
  • 4642

    通过 CTE 更新比其他答案更具可读性:

    ;WITH cte
         AS (SELECT col1,col2,id
             FROM   other_table
             WHERE  sql = 'cool')
    UPDATE A
    SET    A.col1 = B.col1,
           A.col2 = B.col2
    FROM   table A
           INNER JOIN cte B
                   ON A.id = B.id
    
  • 13

    我将Robin's excellent answer修改为以下内容:

    UPDATE Table
    SET Table.col1 = other_table.col1,
     Table.col2 = other_table.col2
    FROM
        Table
    INNER JOIN other_table ON Table.id = other_table.id
    WHERE
        Table.col1 != other_table.col1
    OR Table.col2 != other_table.col2
    OR (
        other_table.col1 IS NOT NULL
        AND Table.col1 IS NULL
    )
    OR (
        other_table.col2 IS NOT NULL
        AND Table.col2 IS NULL
    )
    

    如果没有WHERE子句,您甚至会影响不需要受影响的行,这可能(可能)导致索引重新计算或实际上不应该触发的触发器 .

  • 62
    UPDATE table AS a
    INNER JOIN table2 AS b
    ON a.col1 = b.col1
    INNER JOIN ... AS ...
    ON ... = ...
    SET ...
    WHERE ...
    
  • 49

    如果您使用的是SQL Server,则可以在不指定连接的情况下从另一个表更新一个表,只需将这两个表从 where 子句链接即可 . 这使得SQL查询更加简单:

    UPDATE Table1
    SET Table1.col1 = Table2.col1,
        Table1.col2 = Table2.col2
    FROM
        Table2
    WHERE
        Table1.id = Table2.id
    
  • 40
    UPDATE TQ
    SET TQ.IsProcessed = 1, TQ.TextName = 'bla bla bla'
    FROM TableQueue TQ
    INNER JOIN TableComment TC ON TC.ID = TQ.TCID
    WHERE TQ.IsProcessed = 0
    

    要确保更新所需内容,请先选择

    SELECT TQ.IsProcessed, 1 AS NewValue1, TQ.TextName, 'bla bla bla' AS NewValue2
    FROM TableQueue TQ
    INNER JOIN TableComment TC ON TC.ID = TQ.TCID
    WHERE TQ.IsProcessed = 0
    
  • 1

    像这样;但你必须确保更新表和表后相同 .

    UPDATE Table SET col1, col2
    FROM table
    inner join other_table Table.id = other_table.id
    WHERE sql = 'cool'
    
  • 7

    这是另一个有用的语法:

    UPDATE suppliers
    SET supplier_name = (SELECT customers.name
                         FROM customers
                         WHERE customers.customer_id = suppliers.supplier_id)
    WHERE EXISTS (SELECT customers.name
                  FROM customers
                  WHERE customers.customer_id = suppliers.supplier_id);
    

    它使用“WHERE EXIST”检查它是否为null .

  • 12

    使用别名:

    UPDATE t
       SET t.col1 = o.col1
      FROM table1 AS t
             INNER JOIN 
           table2 AS o 
             ON t.id = o.id
    
  • 548

    在这里整合所有不同的方法 .

    • 选择更新

    • 使用公用表表达式进行更新

    • 合并

    示例表结构如下,并将从Product_BAK更新为Product表 .

    产品

    CREATE TABLE [dbo].[Product](
        [Id] [int] IDENTITY(1, 1) NOT NULL,
        [Name] [nvarchar](100) NOT NULL,
        [Description] [nvarchar](100) NULL
    ) ON [PRIMARY]
    

    Product_BAK

    CREATE TABLE [dbo].[Product_BAK](
            [Id] [int] IDENTITY(1, 1) NOT NULL,
            [Name] [nvarchar](100) NOT NULL,
            [Description] [nvarchar](100) NULL
        ) ON [PRIMARY]
    

    1.选择更新

    update P1
        set Name = P2.Name
        from Product P1
        inner join Product_Bak P2 on p1.id = P2.id
        where p1.id = 2
    

    2.使用公用表表达式进行更新

    ; With CTE as
        (
            select id, name from Product_Bak where id = 2
        )
        update P
        set Name = P2.name
        from  product P  inner join CTE P2 on P.id = P2.id
        where P2.id = 2
    

    3.合并

    Merge into product P1
        using Product_Bak P2 on P1.id = P2.id
    
        when matched then
        update set p1.[description] = p2.[description], p1.name = P2.Name;
    

    在Merge语句中,如果没有在目标中找到匹配的记录,我们可以进行插入,但是在源代码中存在并且请找到语法:

    Merge into product P1
        using Product_Bak P2 on P1.id = P2.id;
    
        when matched then
        update set p1.[description] = p2.[description], p1.name = P2.Name;
    
        WHEN NOT MATCHED THEN
        insert (name, description)
        values(p2.name, P2.description);
    
  • 185

    对于记录(以及其他像我一样的搜索),你可以在MySQL中这样做:

    UPDATE first_table, second_table
    SET first_table.color = second_table.color
    WHERE first_table.id = second_table.foreign_id
    
  • 81

    另一种未提及的可能性是将 SELECT 语句本身放入CTE然后更新CTE .

    ;WITH CTE
         AS (SELECT T1.Col1,
                    T2.Col1 AS _Col1,
                    T1.Col2,
                    T2.Col2 AS _Col2
             FROM   T1
                    JOIN T2
                      ON T1.id = T2.id
             /*Where clause added to exclude rows that are the same in both tables
               Handles NULL values correctly*/
             WHERE EXISTS(SELECT T1.Col1,
                                 T1.Col2
                           EXCEPT
                           SELECT T2.Col1,
                                  T2.Col2))
    UPDATE CTE
    SET    Col1 = _Col1,
           Col2 = _Col2
    

    这样做的好处是可以很容易地首先运行 SELECT 语句来检查结果,但是如果在源表和目标表中它们的名称相同,它确实要求您对列进行别名 .

    这也与其他四个答案中显示的专有 UPDATE ... FROM 语法具有相同的限制 . 如果源表位于一对多连接的许多一侧,则不确定哪些可能的匹配连接记录将在 Update 中使用(如果尝试尝试,则通过引发错误来避免 MERGE 的问题不止一次更新同一行) .

  • 97

    从select语句更新的另一种方法:

    UPDATE A
    SET A.col = A.col,B.col1 = B.col1
    FROM  first_Table AS A
    INNER JOIN second_Table AS B  ON A.id = B.id WHERE A.col2 = 'cool'
    
  • 35

    单程

    UPDATE t 
    SET t.col1 = o.col1, 
        t.col2 = o.col2
    FROM 
        other_table o 
      JOIN 
        t ON t.id = o.id
    WHERE 
        o.sql = 'cool'
    
  • 16

    在SQL Server 2008(或更高版本)中,使用MERGE

    MERGE INTO YourTable T
       USING other_table S 
          ON T.id = S.id
             AND S.tsql = 'cool'
    WHEN MATCHED THEN
       UPDATE 
          SET col1 = S.col1, 
              col2 = S.col2;
    

    或者:

    MERGE INTO YourTable T
       USING (
              SELECT id, col1, col2 
                FROM other_table 
               WHERE tsql = 'cool'
             ) S
          ON T.id = S.id
    WHEN MATCHED THEN
       UPDATE 
          SET col1 = S.col1, 
              col2 = S.col2;
    
  • 45

    这可能是执行更新的一个利基理由(例如,主要用于过程),或者对其他人来说可能是显而易见的,但是还应该声明您可以在不使用连接的情况下执行update-select语句(如果是您正在更新的表没有公共字段) .

    update
        Table
    set
        Table.example = a.value
    from
        TableExample a
    where
        Table.field = *key value* -- finds the row in Table 
        AND a.field = *key value* -- finds the row in TableExample a
    
  • 257
    declare @tblStudent table (id int,name varchar(300))
    declare @tblMarks table (std_id int,std_name varchar(300),subject varchar(50),marks int)
    
    insert into @tblStudent Values (1,'Abdul')
    insert into @tblStudent Values(2,'Rahim')
    
    insert into @tblMarks Values(1,'','Math',50)
    insert into @tblMarks Values(1,'','History',40)
    insert into @tblMarks Values(2,'','Math',30)
    insert into @tblMarks Values(2,'','history',80)
    
    
    select * from @tblMarks
    
    update m
    set m.std_name=s.name
     from @tblMarks as m
    left join @tblStudent as s on s.id=m.std_id
    
    select * from @tblMarks
    
  • 144

    使用:

    drop table uno
    drop table dos
    
    create table uno
    (
        uid int,
        col1 char(1),
        col2 char(2)
    )
    create table dos
    (
        did int,
        col1 char(1),
        col2 char(2),
        [sql] char(4)
    )
    insert into uno(uid) values (1)
    insert into uno(uid) values (2)
    insert into dos values (1,'a','b',null)
    insert into dos values (2,'c','d','cool')
    
    select * from uno 
    select * from dos
    

    无论是:

    update uno set col1 = (select col1 from dos where uid = did and [sql]='cool'), 
    col2 = (select col2 from dos where uid = did and [sql]='cool')
    

    要么:

    update uno set col1=d.col1,col2=d.col2 from uno 
    inner join dos d on uid=did where [sql]='cool'
    
    select * from uno 
    select * from dos
    

    如果两个表中的ID列名相同,则只需将表名放在要更新的表之前,并使用所选表的别名,即:

    update uno set col1 = (select col1 from dos d where uno.[id] = d.[id] and [sql]='cool'),
    col2  = (select col2 from dos d where uno.[id] = d.[id] and [sql]='cool')
    
  • 48

    如果你想加入自己的表(这不会经常发生):

    update t1                    -- just reference table alias here
    set t1.somevalue = t2.somevalue
    from table1 t1               -- these rows will be the targets
    inner join table1 t2         -- these rows will be used as source
    on ..................        -- the join clause is whatever suits you
    
  • 33

    我只是添加了这个,所以你可以看到一个快速的方法来编写它,以便你可以检查在更新之前将更新的内容 .

    UPDATE Table 
    SET  Table.col1 = other_table.col1,
         Table.col2 = other_table.col2 
    --select Table.col1, other_table.col,Table.col2,other_table.col2, *   
    FROM     Table 
    INNER JOIN     other_table 
        ON     Table.id = other_table.id
    
  • 31

    如果使用MySQL而不是SQL Server,则语法为:

    UPDATE Table1
    INNER JOIN Table2
    ON Table1.id = Table2.id
    SET Table1.col1 = Table2.col1,
        Table1.col2 = Table2.col2
    
  • 31

    在接受的答案中,在:

    SET
    Table_A.col1 = Table_B.col1,
    Table_A.col2 = Table_B.col2
    

    我想补充一下:

    OUTPUT deleted.*, inserted.*
    

    我通常做的是将所有内容放在一个支持滚动的事务中并使用 "OUTPUT" :这样我就能看到即将发生的一切 . 当我对所看到的内容感到满意时,我将 ROLLBACK 更改为 COMMIT .

    我通常需要记录我所做的事情,因此在运行roll-backed查询时我使用 "results to Text" 选项,并保存脚本和OUTPUT的结果 . (当然,如果我改变太多行,这是不切实际的)

  • 19

    UPDATE from SELECT with INNER JOIN in SQL Database

    由于这篇文章的回复太多,而且投票率最高,我想我也会在这里提出我的建议 . 虽然这个问题非常有趣,但我在许多论坛网站上都看到了并使用 INNER JOIN 制作了截图解决方案 .

    首先,我创建了一个名为 schoolold 的表,并插入了几个与其列名相关的记录并执行它 .

    然后我执行了 SELECT 命令来查看插入的记录 .

    然后我创建了一个名为 schoolnew 的新表,并且类似地执行了以上行动 .

    然后,要在其中查看插入的记录,我执行SELECT命令 .

    现在,我想在第三和第四行做一些更改,为了完成这个动作,我用 INNER JOIN 执行 UPDATE 命令 .

    要查看更改,请执行 SELECT 命令 .

    您可以通过使用带有UPDATE语句的INNER JOIN来查看表 schoolold 的第三条和第四条记录如何通过表 schoolnew 轻松替换 .

  • 16

    另一种方法是使用派生表:

    UPDATE t
    SET t.col1 = a.col1
        ,t.col2 = a.col2
    FROM (
    SELECT id, col1, col2 FROM @tbl2) a
    INNER JOIN @tbl1 t ON t.id = a.id
    

    样本数据

    DECLARE @tbl1 TABLE (id INT, col1 VARCHAR(10), col2 VARCHAR(10))
    DECLARE @tbl2 TABLE (id INT, col1 VARCHAR(10), col2 VARCHAR(10))
    
    INSERT @tbl1 SELECT 1, 'a', 'b' UNION SELECT 2, 'b', 'c'
    
    INSERT @tbl2 SELECT 1, '1', '2' UNION SELECT 2, '3', '4'
    
    UPDATE t
    SET t.col1 = a.col1
        ,t.col2 = a.col2
    FROM (
    SELECT id, col1, col2 FROM @tbl2) a
    INNER JOIN @tbl1 t ON t.id = a.id
    
    SELECT * FROM @tbl1
    SELECT * FROM @tbl2
    
  • 14

    以下解决方案适用于MySQL数据库:

    UPDATE table1 a , table2 b 
    SET a.columname = 'some value' 
    WHERE b.columnname IS NULL ;
    
  • 13
    UPDATE
        Table_A
    SET
        Table_A.col1 = Table_B.col1,
        Table_A.col2 = Table_B.col2
    FROM
        Some_Table AS Table_A
        INNER JOIN Other_Table AS Table_B
            ON Table_A.id = Table_B.id
    WHERE
        Table_A.col3 = 'cool'
    
  • 1

    甚至有一个 shorter method ,你可能会感到惊讶:

    样本数据集:

    CREATE TABLE #SOURCE ([ID] INT, [Desc] VARCHAR(10));
    CREATE TABLE #DEST   ([ID] INT, [Desc] VARCHAR(10));
    
    INSERT INTO #SOURCE VALUES(1,'Desc_1'), (2, 'Desc_2'), (3, 'Desc_3');
    INSERT INTO #DEST   VALUES(1,'Desc_4'), (2, 'Desc_5'), (3, 'Desc_6');
    

    码:

    UPDATE #DEST
    SET #DEST.[Desc] = #SOURCE.[Desc]
    FROM #SOURCE
    WHERE #DEST.[ID] = #SOURCE.[ID];
    
  • 19

    您可以在此处使用sql server中的更新

    UPDATE
        T1
    SET
       T1.col1 = T2.col1,
       T1.col2 = T2.col2
    FROM
       Table1 AS T1
    INNER JOIN Table2 AS T2
        ON T1.id = T2.id
    WHERE
        T1.col3 = 'cool'
    

相关问题