Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perform INSERT with SELECT to insert multiple records

In the diagram below there is a 1:1 relationship between 'DodgyOldTable' and 'MainTable'. Table 'Option' contains records with 'OptionVal1', 'OptionVal2' and 'OptionVal3' in the 'OptionDesc' field. I need to do an insert into MainTable_Option with a select from DodgyOldTable. Something like this:

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

If possible I want to avoid using several different select statements to perform the insert operation.

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

like image 259
Matthew Dresser Avatar asked Mar 02 '09 10:03

Matthew Dresser


5 Answers

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')
like image 143
Tomalak Avatar answered Nov 19 '22 09:11

Tomalak


My experience is it is often more easy and more readable to divide it up into smaller bits. So don't try to do everything in one single query. Especially when you are making migration scripts this should not be an issue.

Write down the steps, maybe introduce a temporary table, write the scripts to migrate your data and you are good to go!

like image 36
Roel Snetselaar Avatar answered Nov 19 '22 11:11

Roel Snetselaar


What about CROSS JOIN solution?

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
like image 43
Maksym Gontar Avatar answered Nov 19 '22 11:11

Maksym Gontar


perhaps not the most efficient solution but by using a union, this should work.

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'
like image 2
Lieven Keersmaekers Avatar answered Nov 19 '22 11:11

Lieven Keersmaekers


11 Yrs later but might help someone:

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 come from the same select

col3, col5 are static strings

col4 is the current system time

col6 a Num value,

col7 from a select that returns one value.

NB: Ensure the select with multiple values comes at the beginning. This is MySQL

like image 2
kmihingo Avatar answered Nov 19 '22 11:11

kmihingo