【问题标题】:SQL Server : IF NOT EXISTS MULTIPLESQL Server:如果不存在多个
【发布时间】:2017-10-05 20:11:11
【问题描述】:

我需要在一个表中插入多行。我通过从另一个表中选择行并将它们插入到所需的表中来做到这一点。

问题是我需要插入的一两行可能已经存在。如何在插入许多行的插入上执行IF NOT EXISTS,如下面的示例所示?

BEGIN TRAN
    INSERT INTO [main].[dbo].[product_usa] 
        SELECT *
        FROM [main].[dbo].[product_mxo]
        WHERE tag_key IN ('15652', '16161', '11431', '16214',  '16215',  '16216', 
                          '16213', '16217', '16218',  '16222') 
          AND edition_key = '1'  
          AND product_key = '1'
-- COMMIT 
-- ROLLBACK 

【问题讨论】:

    标签: sql sql-server sql-server-2008 insert


    【解决方案1】:

    如果tag_keyproduct_usaproduct_mxo 中都是pk 只需添加exists 以验证tag_key 不存在。

    INSERT INTO [main].[dbo].[product_usa] 
        SELECT *
        FROM   [main].[dbo].[product_mxo] mxo
        WHERE  tag_key IN 
            ('15652', '16161', '11431',
             '16214', '16215', '16216', 
             '16213', '16217', '16218', 
             '16222') 
         AND edition_key = '1'  
         AND product_key = '1'
         AND NOT EXISTS (SELECT 1 
                         FROM [main].[dbo].[product_usa] usa
                         WHERE us.tag_key = mxo.tag_key)
    

    【讨论】:

    • 0 行受影响。我不确定如何对此进行扩展,但有些行应该会受到影响。
    • 查询看起来没问题。试试SELECT * FROM [main].[dbo].[product_usa] usa WHERE tag_key IN ('15652', '16161', '11431', '16214', '16215', '16216', '16213', '16217', '16218', '16222') 带来什么结果?然后对mxo做同样的事情
    【解决方案2】:

    您可以像这样添加EXISTS

    BEGIN TRAN
    INSERT INTO [main].[dbo].[product_usa] 
        SELECT *
        FROM   [main].[dbo].[product_mxo]
        WHERE  tag_key IN 
        (
            '15652', 
            '16161',
            '11431',
            '16214', 
            '16215', 
            '16216', 
            '16213', 
            '16217', 
            '16218', 
            '16222'
        ) AND edition_key = '1'  AND product_key = '1'
        AND NOT EXISTS(SELECT * FROM [main].[dbo].[product_usa] WHERE /* Column Comparison */ )
    

    【讨论】:

      【解决方案3】:

      假设 tag_key 是主键或唯一键,您可以这样做:

      INSERT INTO [main].[dbo].[product_usa] 
          SELECT *
          FROM   [main].[dbo].[product_mxo] t
          WHERE  tag_key IN 
          (
              '15652', 
              '16161',
              '11431',
              '16214', 
              '16215', 
              '16216', 
              '16213', 
              '16217', 
              '16218', 
              '16222'
          ) AND edition_key = '1'  AND product_key = '1'
          AND NOT EXISTS (SELECT 1 FROM [main].[dbo].[product_usa] x WHERE t.tag_key = x.tag_key)
      

      如果您想要所有不存在的记录,只需摆脱其他 where 条件

      INSERT INTO [main].[dbo].[product_usa] 
          SELECT *
          FROM   [main].[dbo].[product_mxo] t
          WHERE
             NOT EXISTS (SELECT 1 FROM [main].[dbo].[product_usa] x WHERE t.tag_key = x.tag_key)
      

      【讨论】:

      • 与@juan 解决方案相同,0 行受影响。
      • @John 是的,他和我同时回答,但他们的回答并不完全相同。阅读 cmets 关于他的回答,您可能应该考虑我回答的第二部分。但是你需要解释你想要什么。例如“我正在尝试将 product_mxo 中的每一行插入 product_usa”,主键是 tag_key 或另一列。或者我正在尝试同步表格,或者我正在尝试插入每个符合 xyz 标准但不存在的产品....如果您无法获得您想要的结果,您很可能会过滤掉太多或不正确的地方
      【解决方案4】:

      在 tag_key 上与目标表进行左外连接并检查空值。

      INSERT INTO [main].[dbo].[product_usa] 
      SELECT m.*
      FROM   [main].[dbo].[product_mxo] m
      LEFT OUTER JOIN [main].[dbo].[product_usa] u
      ON u.tag_key = m.tag_key
      WHERE  m.tag_key IN 
      (
          '15652', 
          '16161',
          '11431',
          '16214', 
          '16215', 
          '16216', 
          '16213', 
          '16217', 
          '16218', 
          '16222'
      ) AND m.edition_key = '1'  AND m.product_key = '1' AND u.tag_key IS NULL
      

      【讨论】:

      • 对不起...你问的是NOT EXISTS。虽然我的回答将解决您描述的问题,但它不使用您询问的工具。我的错...
      猜你喜欢
      • 1970-01-01
      • 2014-01-25
      • 1970-01-01
      • 2011-03-04
      • 2011-09-01
      • 2011-11-17
      • 1970-01-01
      • 2011-01-09
      相关资源
      最近更新 更多