Выполните INSERT с помощью SELECT, чтобы вставить несколько записей

На приведенной ниже диаграмме существует соотношение 1:1 между "DodgyOldTable" и "MainTable". Таблица "Вариант" содержит записи с параметрами "OptionVal1", "OptionVal2" и "OptionVal3" в поле "OptionDesc". Мне нужно сделать вставку в MainTable_Option с выбором из DodgyOldTable. Что-то вроде этого:

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

Ответы

Ответ 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

возможно, не самое эффективное решение, но с помощью объединения это должно работать.

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'

Ответ 3

Мой опыт заключается в том, что часто проще и читабельнее разделить его на более мелкие биты. Поэтому не пытайтесь делать все в одном запросе. Особенно, когда вы выполняете сценарии миграции, это не должно быть проблемой.

Запишите шаги, возможно, представите временную таблицу, напишите сценарии, чтобы перенести свои данные, и вам хорошо идти!

Ответ 4

Как насчет решения 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

Ответ 5

Я бы сказал, что миграция вручную script будет проще в использовании, а затем попытаться сделать это в одном запросе sql, если это вариант.

Ответ 6

Вы можете СОЕДИНИТЬ все выборки вместе, чтобы дать один набор результатов, но это зависит от ваших причин не желать множественных выборов - если их слишком много или количество выборок может часто меняться, все равно будет больно исправлять запрос с дополнительными выделениями. К несчастью, я думаю, что вам придется поместить логику где-нибудь, которая определяет, какой бит DodgyOldTable сопоставляется с новой структурой, и либо записывать перенос script (или пакет SSIS) на массовую миграцию (если это одноразовое задание) или СОЕДИНИТЕ ваши результаты вместе...

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
...