【问题标题】: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
      相关资源
      最近更新 更多