【问题标题】:Perform INSERT with SELECT to insert multiple records使用 SELECT 执行 INSERT 以插入多条记录
【发布时间】:2009-03-02 10:41:48
【问题描述】:

在下图中,“DodgyOldTable”和“MainTable”之间存在 1:1 的关系。表“Option”包含“OptionDesc”字段中具有“OptionVal1”、“OptionVal2”和“OptionVal3”的记录。 我需要从 DodgyOldTable 中选择插入 MainTable_Option。像这样的:

INSERT MainTable_Option ([MainTableID],[OptionID])
SELECT ID, (CASE WHEN OptionVal1 = 'y' THEN 
    (SELECT OptionID 
     FROM Option 
     WHERE OptionDesc = 'OptionVal1') END
FROM DodgyOldTable

如果可能的话,我想避免使用几个不同的选择语句来执行插入操作。

alt text http://www.freeimagehosting.net/uploads/863f10bf5f.jpg

【问题讨论】:

  • 也许只有我,但我看不到附图。
  • @Learning:我自鸣得意的公司代理阻止了图像托管站点。也许对你来说也是这样。

标签: sql sql-server sql-server-2005


【解决方案1】:
INSERT 
  MainTable_Option 
  (
  MainTableID, 
  OptionID
  )
SELECT
  d.ID, 
  o.OptionId
FROM
  DodgyOldTable d
  INNER JOIN Option o ON
    (d.OptionVal1 = 'Y' AND o.OptionDesc = 'OptionVal1') OR
    (d.OptionVal2 = 'Y' AND o.OptionDesc = 'OptionVal2') OR
    (d.OptionVal3 = 'Y' AND o.OptionDesc = 'OptionVal3')

【讨论】:

  • 太棒了!我知道必须有更好的方法!
【解决方案2】:

我的经验是,将其分成更小的部分通常更容易且更易读。所以不要试图在一个查询中完成所有事情。尤其是当您制作迁移脚本时,这应该不是问题。

写下步骤,可能会引入一个临时表,编写脚本来迁移您的数据,一切顺利!

【讨论】:

    【解决方案3】:

    CROSS JOIN 解决方案呢?

    DECLARE @DodgyOldTable TABLE (ID INT, OptionVal1 CHAR, OptionVal2 CHAR, 
      OptionVal3 CHAR)
    INSERT INTO @DodgyOldTable
    SELECT 1, 'y', 'n', 'y' UNION
    SELECT 2, 'y', 'n', 'n' UNION
    SELECT 3, 'n', 'n', 'y' UNION
    SELECT 4, 'y', 'y', 'y' UNION
    SELECT 5, 'n', 'n', 'n'
    
    DECLARE @Option TABLE (OptionID INT, OptionDesc VARCHAR(100))
    INSERT INTO @Option
    SELECT 1, 'OptionVal1' UNION
    SELECT 2, 'OptionVal2' UNION
    SELECT 3, 'OptionVal3'
    
    SELECT ID, OptionID FROM
    (
        SELECT 
            ID, 
            CASE    
              WHEN (OptionVal1 = 'y' AND OptionDesc = 'OptionVal1') 
                OR (OptionVal2 = 'y' AND OptionDesc = 'OptionVal2') 
                OR (OptionVal3 = 'y' AND OptionDesc = 'OptionVal3')
              THEN OptionID 
              ELSE NULL 
            END AS OptionID 
        FROM @DodgyOldTable DOT CROSS JOIN @Option O 
    )CRS
    WHERE OptionID IS NOT NULL
    

    【讨论】:

      【解决方案4】:

      也许不是最有效的解决方案,但通过使用联合,这应该可以工作。

      INSERT MainTable_Option ([MainTableID],[OptionID])
      SELECT ID, (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal1')
      FROM DodgyOldTable dot
      WHERE OptionVal1 = 'y'
      UNION SELECT ID, (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal2')
      FROM DodgyOldTable dot
      WHERE OptionVal2 = 'y'
      UNION SELECT ID, (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal3')
      FROM DodgyOldTable dot
      WHERE OptionVal3 = 'y'
      

      【讨论】:

      • @Lieven:无意冒犯,但我认为不需要在回答中包含称呼和结束语。
      • @Tomalak,没有冒犯。我没有意识到这一点。我认为这是邮件对话中的标准礼貌。最后一次,问候,Lieven :)
      • @Lieven:再次没有冒犯,但我冒昧地删除了称呼并关闭以提高可读性。
      • @lc:我应该自己做。当时,我不知道有什么更好的。感谢您的照顾。
      【解决方案5】:

      11 年后,但可能会帮助某人:

      INSERT INTO schema.tableName (col1, col2,col3, col4, col5, col6, col7)
            SELECT col1, 
                   col2,
                   'Static value',
                   CURRENT_TIMESTAMP,
                   'Anothe static value', 
                   1, 
                   (SELECT col7 FROM schema2.anotherTableName)
             FROM schema.tableX;
      

      col1 & col2 来自同一个选择

      col3、col5 是静态字符串

      col4 是当前系统时间

      col6 一个 Num 值,

      col7 来自返回一个值的选择。

      注意:确保带有多个值的选择出现在开头。 这是 MySQL

      【讨论】:

        【解决方案6】:

        如果可以的话,我会说手动迁移脚本会更容易使用,然后尝试在单个 sql 查询中执行它。

        【讨论】:

          【解决方案7】:

          您可以将所有选择合并在一起以提供一个结果集,但这取决于您不想要多个选择的原因 - 如果选择太多或选择的数量可能经常变化,修改仍然会很痛苦带有附加选择的查询。不幸的是,我认为您必须将逻辑放在某处,以确定 DodgyOldTable 的哪些位映射到新结构,然后编写迁移脚本(或 SSIS 包)进行批量迁移(如果这是一次性工作)或 UNION你的结果在一起......

          INSERT MainTable_Option ([MainTableID],[OptionID])
          SELECT ID, (CASE WHEN OptionVal1 = 'y' THEN (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal1') END
          FROM DodgyOldTable
          WHERE OptionVal1 = 'y
          UNION
          SELECT ID, (CASE WHEN OptionVal2 = 'y' THEN (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal2') END
          FROM DodgyOldTable
          WHERE OptionVal2 = 'y
          ...
          

          【讨论】:

            猜你喜欢
            • 2014-06-05
            • 1970-01-01
            • 2019-09-01
            • 1970-01-01
            • 2011-07-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-22
            相关资源
            最近更新 更多