2009-03-02 21 views
13

下の図には、 'DodgyOldTable'と 'MainTable'の間に1対1の関係があります。テーブル 'Option'には 'OptionDesc'フィールドに 'OptionVal1'、 'OptionVal2'、 'OptionVal3'のレコードが含まれています。 DodgyOldTableからselectを指定してMainTable_Optionに挿入する必要があります。可能であれば、いくつかの異なるselectステートメントを使用して挿入操作を実行しないようにしたいと考えています。複数のレコードを挿入するためにSELECTを使用してINSERTを実行

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

+0

おそらくそれは私ですが、私は添付の写真が見えません。 – Learning

+0

@ラーニング:私の密かな企業のプロキシは、画像ホスティングサイトをブロックします。たぶんそれはあなたのためにもこのようなものです。 – Tomalak

答えて

27
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') 
+0

Brilliant!私は良い方法がなければならないことを知っていた! –

+0

喜んで助けてください。 ;-) – Tomalak

0

私は手動移行スクリプトは、それがオプションである場合、単一のSQLクエリでそれをやろうとし、次に使用する方が簡単だろうと言うと思います。

1

おそらく最も効率的なソリューションではなく、ユニオンを使用することによって、これはうまくいくはずです。

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' 
+0

@リーブン:違反はしませんが、私はあなたの答えに挨拶と終了を含める必要はないと思います。 – Tomalak

+0

@Tomalak、違反はありません。私はそれを知らなかった。私はそれがメールの会話では標準的な礼儀であると考えました。最後に、Lievenについて: –

+0

@Lieven:もう一度犯罪はありませんが、わかりやすさを向上させるために挨拶と終了を取り除く自由を取っています。 –

0

あなたは可能性がありUNION一緒に選択のすべてのセット1件の結果を与えるが、それは、複数の選択を望んでいないためにあなたの理由に依存して - そこにあまりにも多くがあるか、選択の数が頻繁に変わる可能性があり、それはまだだろう追加の選択肢でクエリを修正するための苦痛。残念ながら私はDodgyOldTableのどのビットが新しい構造にマップされるかを決定するロジックをどこかに置かなければならないと思います。また、移行スクリプト(またはSSISパッケージ)をバルクマイグレーション(これは1つのジョブである場合)一緒にあなたの結果...

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

私の経験では、小さいビットにそれを分割することは、しばしば、より簡単で、より読みやすいです。だから、1つのクエリですべてをやろうとしないでください。特に、移行スクリプトを作成しているときは、これは問題ではありません。

手順を書き留めて、一時テーブルを導入し、スクリプトを書き込んでデータを移行してください。

1

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 
関連する問題