【问题标题】:INSERT INTO SELECT with a LEFT JOIN to prevent duplicates, only prevents duplicates already in the table使用 LEFT JOIN 插入 INTO SELECT 以防止重复,仅防止表中已有重复
【发布时间】:2021-07-17 00:43:23
【问题描述】:

关于这种防止重复插入的方法:

INSERT INTO table1 
SELECT t2.col1, 
       t2.col2 
FROM   table2 t2 
       LEFT JOIN table1 t1 
         ON t2.col1 = t1.col1 
            AND t2.col2 = t1.col2 
WHERE  t1.col1 IS NULL 

从我的测试中我可以看出,这将防止来自 Table_2 的任何重复 col1/col2 组合已经在 Table_1 中,但它不会阻止相同的 col1/col2 组合从 Table_2 中多次传入。我是否认为在 LEFT JOIN 中对 Table_1 的引用可以被认为是查询开始前 Table_1 的“快照”,因此它没有任何新的 col1/col2 组合的可见性作为查询本身的一部分从 Table_2 添加?

如果这是正确的,并且有没有办法检查传入源表中的重复数据,而无需采取额外的源重复数据删除步骤(在我的实际情况下,源将是两个表 INNER JOINed)?

谢谢

【问题讨论】:

    标签: sql-server duplicates left-join


    【解决方案1】:

    您在“快照”这一点上是正确的:在此查询中对table1 的任何插入都不会影响LEFT JOIN table1

    但是您仍然需要DISTINCT 来保证查询数据的唯一性。

    INSERT INTO table1 
    SELECT DISTINCT
           t2.col1, 
           t2.col2 
    FROM   table2 t2 
           LEFT JOIN table1 t1 
             ON t2.col1 = t1.col1 
                AND t2.col2 = t1.col2 
    WHERE  t1.col1 IS NULL 
    

    但是:

    • LEFT JOINNOT EXISTSEXCEPT 的一个穷人的替代品,优化器理解得更好
    • 您应该始终在INSERT 中指定列名

    所以您的代码应该看起来像以下选项之一:

    INSERT INTO table1 (col1, col2)
    SELECT DISTINCT
           t2.col1, 
           t2.col2 
    FROM   table2 t2 
    WHERE NOT EXISTS (SELECT 1
           FROM table1 t1 
             WHERE t2.col1 = t1.col1 
                AND t2.col2 = t1.col2);
    
    
    
    INSERT INTO table1 (col1, col2)
    SELECT DISTINCT
           t2.col1, 
           t2.col2 
    FROM   table2 t2 
    WHERE NOT EXISTS (                    -- or you can use EXISTS/EXCEPT
           SELECT t2.col1, t2.col2
           INTERSECT
           SELECT t1.col1, t1.col2
           FROM table1 t1);
    
    
    
    INSERT INTO table1 (col1, col2)
    SELECT                  -- EXCEPT implies DISTINCT
           t2.col1, 
           t2.col2 
    FROM   table2 t2
    EXCEPT
    SELECT t1.col1, t1.col2
    FROM table1 t1;
    

    【讨论】:

    • 谢谢,非常感谢。这很有帮助。
    猜你喜欢
    • 2015-08-05
    • 2015-08-07
    • 2016-02-19
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2018-04-11
    相关资源
    最近更新 更多