首页 文章

在SQL Server中使用JOIN更新表?

提问于
浏览
719

我想更新一个表中的列,在其他表上进行连接,例如:

UPDATE table1 a 
INNER JOIN table2 b ON a.commonfield = b.[common field] 
SET a.CalculatedColumn= b.[Calculated Column]
WHERE 
    b.[common field]= a.commonfield
AND a.BatchNO = '110'

但它抱怨:

消息170,级别15,状态1,行2第2行:'a'附近的语法不正确 .

这有什么不对?

10 回答

  • 1

    试试这样:

    begin tran
        UPDATE a 
        SET a.CalculatedColumn= b.[Calculated Column]
        FROM table1 a INNER JOIN table2 b ON a.commonfield = b.[common field] 
        WHERE a.BatchNO = '110'
    commit tran
    

    (编辑:错误拼写!)

  • 3

    亚伦上面给出的答案是完美的:

    UPDATE a
      SET a.CalculatedColumn = b.[Calculated Column]
      FROM Table1 AS a
      INNER JOIN Table2 AS b
      ON a.CommonField = b.[Common Field]
      WHERE a.BatchNo = '110';
    

    只是想在我们尝试在更新该表时使用表的别名时添加为什么在SQL Server中出现此问题,下面提到的语法总是会给出错误:

    update tableName t 
    set t.name = 'books new' 
    where t.id = 1
    

    如果要更新单个表或使用join进行更新,则case可以是any .

    虽然上面的查询在PL / SQL中可以正常工作,但在SQL Server中却不行 .

    在SQL Server中使用表别名时更新表的正确方法是:

    update t 
    set t.name = 'books new' 
    from tableName t 
    where t.id = 1
    

    希望它能帮助每个人为什么错误来到这里 .

  • -4

    尝试:

    UPDATE table1
    SET CalculatedColumn = ( SELECT [Calculated Column] 
                             FROM table2 
                             WHERE table1.commonfield = [common field])
    WHERE  BatchNO = '110'
    
  • 2

    似乎SQL Server 2012也可以处理Teradata的旧更新语法:

    UPDATE a
    SET a.CalculatedColumn= b.[Calculated Column]
    FROM table1 a, table2 b 
    WHERE 
        b.[common field]= a.commonfield
    AND a.BatchNO = '110'
    

    如果我没记错的话,当我尝试类似查询时,2008R2会出错 .

  • 2

    另一种方法是使用MERGE

    ;WITH cteTable1(CalculatedColumn, CommonField)
      AS
      (
        select CalculatedColumn, CommonField from Table1 Where BatchNo = '110'
      )
      MERGE cteTable1 AS target
        USING (select "Calculated Column", "Common Field" FROM dbo.Table2) AS source ("Calculated Column", "Common Field")
        ON (target.CommonField = source."Common Field")
        WHEN MATCHED THEN 
            UPDATE SET target.CalculatedColumn = source."Calculated Column";
    

    -Merge是SQL Standard的一部分

  • 0

    我有同样的问题..你不需要添加一个物理列..因为现在你必须维护它..你可以做的是在select查询中添加一个通用列:

    EX:

    select tb1.col1, tb1.col2, tb1.col3 ,
    ( 
    select 'Match' from table2 as tbl2
    where tbl1.col1 = tbl2.col1 and tab1.col2 = tbl2.col2
    )  
    from myTable as tbl1
    
  • 26

    你没有't quite have SQL Server'的专有 UPDATE FROM 语法 . 也不确定为什么你需要加入 CommonField 并在之后过滤它 . 试试这个:

    UPDATE t1
      SET t1.CalculatedColumn = t2.[Calculated Column]
      FROM dbo.Table1 AS t1
      INNER JOIN dbo.Table2 AS t2
      ON t1.CommonField = t2.[Common Field]
      WHERE t1.BatchNo = '110';
    

    如果您正在做一些非常愚蠢的事情 - 比如不断尝试将一列的值设置为另一列的聚合(这违反了避免存储冗余数据的原则),您可以使用a CTE (common table expression)

    ;WITH t2 AS
    (
      SELECT [key], CalculatedColumn = SUM(some_column)
        FROM dbo.table2
        GROUP BY [key]
    )
    UPDATE t1
      SET t1.CalculatedColumn = t2.CalculatedColumn
      FROM dbo.table1 AS t1
      INNER JOIN t2
      ON t1.[key] = t2.[key];
    

    这真的很愚蠢的原因是,每当 table2 中的任何一行发生变化时,你都必须重新运行整个更新 . SUM 是您可以随时在运行时计算的东西,在这样做时,永远不必担心结果是陈旧的 .

  • 38
    MERGE table1 T
       USING table2 S
          ON T.CommonField = S."Common Field"
             AND T.BatchNo = '110'
    WHEN MATCHED THEN
       UPDATE
          SET CalculatedColumn = S."Calculated Column";
    
  • 1386
    UPDATE mytable
             SET myfield = CASE other_field
                 WHEN 1 THEN 'value'
                 WHEN 2 THEN 'value'
                 WHEN 3 THEN 'value'
             END
        From mytable
        Join otherTable on otherTable.id = mytable.id
        Where othertable.somecolumn = '1234'
    

    更多替代方案:http://www.karlrixon.co.uk/writing/update-multiple-rows-with-different-values-and-a-single-sql-query/

  • 0

    我发现在更新之前将UPDATE转换为SELECT以获取我想要更新的行作为测试是有用的 . 如果我可以选择我想要的确切行,我可以只更新我想要更新的行 .

    DECLARE @expense_report_id AS INT
    SET @expense_report_id = 1027
    
    --UPDATE expense_report_detail_distribution
    --SET service_bill_id = 9
    
    SELECT *
    FROM expense_report_detail_distribution erdd
    INNER JOIN expense_report_detail erd
    INNER JOIN expense_report er 
        ON er.expense_report_id = erd.expense_report_id 
        ON erdd.expense_report_detail_id = erd.expense_report_detail_id
    WHERE er.expense_report_id = @expense_report_id
    

相关问题