更短的查询方法

时间:2012-01-09 09:36:31

标签: sql sql-server-2008 tsql

源表和目标表都有大约40列。要更新的行数约为20.目标表的行数约为30k。

下面是否有更好的(更短的查询)方法?

UPDATE destination_table t1
SET 
field1 = (select field1 from src_table t2 where t2.pk = t1.pk),
field2 = (select field2 from src_table t2 where t2.pk = t1.pk),
... 
field40 = (select field40 from src_table t2 where t2.pk = t1.pk),
WHERE EXISTS (select 1 from src_table t2 where t2.pk = t1.pk)

3 个答案:

答案 0 :(得分:5)

您可以使用以下内容:

UPDATE      dest
SET         dest.Field1 = src.Field1,
            dest.Field2 = src.Field2,
            dest.Field3 = src.Field3,
            dest.Field4 = src.Field4,
            dest.Field5 = src.Field5,
            dest.Field6 = src.Field6
FROM        destination_table dest
INNER JOIN  src_table src
ON          src.pk = dest.pk

您只需添加额外字段即可进行更新。

答案 1 :(得分:3)

update t1 set
    field1 = t2.field1,
    field2 = t2.field2,
    ... 
    field40 = t2.field40,
from destination_table t1
join src_table t2 on t2.pk = t1.pk

已添加(评论后):

在我看来,避免动态查询会更好,但如果你真的想要,你可以按照下面的方式去做。生成查询,无需记下所有列,但所有列都将更新。

declare @sql as nvarchar(max)
set @sql = ''

select @sql = @sql + ', ' + column_name + ' = t2.' + column_name
from information_schema.columns
where table_name = 'destination_table'

set @sql =
    'update t1 set ' + 
    stuff(@sql, 1, 2, '') +
    ' from destination_table t1 join src_table t2 on t2.pk = t1.pk'

exec sp_executesql @sql

答案 2 :(得分:1)

您的原始查询是标准SQL-92'标量子查询'方法**。更喜欢它的一个原因(除了可移植性的概念)是SQL Server的专有UPDATE..FROM..JOIN语法提供了可能模糊和意外的结果。

然而,'标量子查询'方法毫无疑问是冗长的(尽管智能优化器会发现重复的代码)。作为一个reault,SQL-99标准引入了MERGE语句,该语句在SQL Server 2008中实现(有用的扩展),例如

MERGE INTO destination_table
   USING src_table t2
      ON t2.pk = destination_table.pk
WHEN MATCHED THEN
   UPDATE 
      SET field1 = T2.field1, 
          field2 = T2.field2, 
          field2 = T2.field3, 
          ...
          field40 = T2.field40;

由于您不支持传统(2008年之前)代码,并且假设您没有立即计划移植到不支持MERGE的SQL产品(注意Oracle和postgreSQL没有,而mySQL没有),我认为没有理由使用MERGE以外的任何构造进行此类更新。


**好吧,差不多。您的更新以具有相关名称't1`的表为目标。在SQL-92中,相关名称应该具有在SQL语句末尾实现超出范围的表的效果。换句话说,虽然语法有效,但结果应该是底层基表中的数据不受影响。但是,似乎很明显这不是您更新的意图,实际上SQL Server的实际效果是基表受到影响,技术上不符合规范的行为!