【问题标题】:compare rows and update if different values and insert if doesn't exist如果不同的值比较行并更新,如果不存在则插入
【发布时间】:2018-08-17 05:43:46
【问题描述】:

我有一个 TABLE1 和 TABLE2 具有相同的列(大约 15 个),除了 TABLE2 有额外的日期字段。如果行不存在,我正在尝试遍历 TABLE1(大约 25,000)行并插入到 TABLE2 中。 这可以毫无问题地完成,但我只想在任何列值与 TABLE1 不同时更新 TABLE2。我是否必须手动检查比较每个列的值并更新?我找不到任何更简单的方法来做到这一点。我之所以这样做,是因为我只想在有任何更新或插入时才将一行插入历史表中。

begin
   update table set ...
   where key = @key
end
else
begin
   insert into table (key, ...)
   values (@key, ...)
end

【问题讨论】:

标签: c# sql-server tsql sql-server-2016


【解决方案1】:

+1 用于推荐 MERGE,因为这是一种可以在单个语句中处理两个实例的正确方法。如果您不熟悉它,可以运行两个单独的语句(UPDATE/INSERT)。

对于更新:

如果您想根据您加入的任何键不相等的任何列进行更新,则相当简单。您可以从任一表中获取所有列的列表(最简单的方法是右键单击该表并选择 TOP 1000)。

突出显示列并按 Shift + Tab 并使用 CTRL + F 删除所有逗号,全部替换。将其复制并粘贴到 Excel 的 A 列中。

在 B 列中插入以下公式:

B1:="T1."&A1&" <> T2."&A1&","

B2:="OR T1."&A2&" = T2."&A2&","

将 B2 中的公式复制并粘贴到列表的下方。所以:

UPDATE T1
SET T1.Column1 = T2.Column1
    ,T1.Column2 = T2.Column2
    ,T1.Column3 = T2.Column3
    ,T1.Column4 = T2.Column4
FROM Table1 T1
INNER JOIN Table2 T2
    ON T1.Table1PrimaryKey = T2.Table2PrimaryKey
WHERE T1.Column1 <> T2.Column1
    OR T1.Column2 <> T2.Column2
    OR T1.Column3 <> T2.Column3
    OR T1.Column4 <> T2.Column4

注意:因为如果任何列组合不匹配,所有被比较的列都会被更新,那么你就可以了,因为更新匹配的列不会有任何损害。而且,如果您正在实施一个缓慢变化的维度来跟踪日期变化,那么更新的日期仍然有效,因为至少有 一个 列记录不匹配并因此被更新。

对于插入:

INSERT INTO Table1 (Column1, Column2, Column3, Column4)
SELECT T2.Column1
    ,T2.Column2
    ,T2.Column3
    ,T2.Column4
FROM Table2 T2
WHERE T2.Table2PrimaryKey NOT EXISTS (SELECT T1.Table1PrimaryKey FROM Table1 T1)
ORDER BY T2.Table2PrimaryKey

注意:上面的 INSERT 假设您的 PrimaryKey 列是 IDENTITY 列,因为它是自动计算的,所以不能插入。如果您使用的主键不是 IDENTITY 字段,则需要将其包含在 INSERT 子句中。此外,ORDER BY 将按照 PRIMARY KEY 的顺序插入记录。这在 PRIMARY KEY 是 IDENTITY 字段时很有用,因为计算的值至少会按照它的来源顺序排列。如果所有 INSERTS 都使用此方法,并且目标表仅从接收表接收记录,并且没有任何 RESEED 或删除,则 IDENTITY 主键列值将相同。

【讨论】:

    【解决方案2】:

    你需要一次做一列
    如果你有一些 null 你需要做检查

    insert into history 
    select t1.id, t1.col1, t2.col1  
    from table2 t2 
    join table1 t1 
      on t2.id = t1.id  
     and t1.col1 <> t2.col 
    
    update t2 
    set t2.col1 = t1.col1 
    from table2 t2 
    join table1 t1 
      on t2.id = t1.id 
     and t1.col1 <> t2.col
    

    您也可以使用输出子句进行更新

    对于插入使用not exists

    【讨论】:

    • 那么你会知道哪一列是从时间戳更新的吗?抱歉,我无法为您提供更多帮助。
    【解决方案3】:

    假设您需要多次执行此操作,我建议您在表 A 上使用插入和更新触发器,以使表 B 保持最新。

    【讨论】:

      猜你喜欢
      • 2012-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      • 2015-03-31
      • 1970-01-01
      相关资源
      最近更新 更多