Search code examples
t-sqlinsertpivotpivot-tableunpivot

complex SQL INSERT not working


I am working on migrating data from 1 row by X columns in one table to X rows in another table. In the first table, multiple boolean records AF.AdditionalFieldsBoolean15 (and 14, 13, 12, etc) are stored in a single row. I need to create a single row to represent each 'true' boolean column.

I have been working with the following code, which executes flawlessly, except that it only inserts 1 record. When I run the SELECT statement in the second code block, I return 12 records. How do I ensure that I am iterating over all records?

BEGIN TRAN TEST

DECLARE @id uniqueidentifier = NEWID()
DECLARE @dest uniqueidentifier = 'AC34C8E5-8859-4E74-ACF2-54B3804AE9C9'
DECLARE @person uniqueidentifier

SELECT @person = GP.Oid FROM <Redacted>.GenericPerson AS GP

INNER JOIN <Redacted>.AdditionalFields AS AF
ON GP.AdditionalFields = AF.Oid

WHERE AF.AdditionalBoolean15 = 'true'

INSERT INTO <Redacted>.Referral (Oid, Destination, Person)
OUTPUT INSERTED.*
VALUES (@id, @dest, @person)

Select statement that returns 12 records

SELECT *
FROM WS_Live.dbo.GenericPerson AS GP
INNER JOIN WS_Live.dbo.AdditionalFields AS AF
ON GP.AdditionalFields = AF.Oid

WHERE AF.AdditionalBoolean15 = 'true'

|

|

|

|

|

|

--------------SOLUTION (EDIT)--------------------

Thanks to M.Ali I was able to muddle through pivot tables and worked out the following solution. Just wanted to post with some explanation in case anyone needs this in the future.

INSERT INTO <Redacted>.Referral (Person, Destination, Oid)
OUTPUT INSERTED.*
SELECT   Person
       , Destination
       , NEWID() AS Oid
FROM     
(
    SELECT 
    GP.Oid AS Person, 
    AF.AdditionalBoolean15 AS 'AC34C8E5-8859-4E74-ACF2-54B3804AE9C9', 
    AF.AdditionalBoolean14 AS '7DE4B414-42E0-4E39-9432-6DC9F60A5512',
    AF.AdditionalBoolean8  AS '5760A126-AD15-4FF4-B608-F1C4220C7087',
    AF.AdditionalBoolean13 AS '4EFFB0FB-BB6C-4425-9653-D482B6C827AC',
    AF.AdditionalBoolean17 AS '0696C571-EEFA-4FE6-82DA-4FF6AB96CC98',
    AF.AdditionalBoolean4  AS 'FF381D63-A76C-46F1-8E2C-E2E3C69365BF',
    AF.AdditionalBoolean20 AS 'C371E419-4E34-4F46-B07D-A4533491D944',
    AF.AdditionalBoolean16 AS '1F0D1221-76D7-4F1F-BB7A-818BB26E0590',
    AF.AdditionalBoolean18 AS 'C6FD53A8-37B9-4519-A825-472722A158C9',
    AF.AdditionalBoolean19 AS 'BEBD6ED6-AF0A-4A05-A1C1-060B2926F83E'

    FROM <Redacted>.GenericPerson GP
    INNER JOIN <Redacted>.AdditionalFields AF
    ON GP.AdditionalFields = AF.Oid 

)AS cp

UNPIVOT 
( 
    Bool FOR Destination IN ([AC34C8E5-8859-4E74-ACF2-54B3804AE9C9],
                             [7DE4B414-42E0-4E39-9432-6DC9F60A5512],
                             [5760A126-AD15-4FF4-B608-F1C4220C7087],
                             [4EFFB0FB-BB6C-4425-9653-D482B6C827AC],
                             [0696C571-EEFA-4FE6-82DA-4FF6AB96CC98],
                             [FF381D63-A76C-46F1-8E2C-E2E3C69365BF],
                             [C371E419-4E34-4F46-B07D-A4533491D944],
                             [1F0D1221-76D7-4F1F-BB7A-818BB26E0590],
                             [C6FD53A8-37B9-4519-A825-472722A158C9],
                             [BEBD6ED6-AF0A-4A05-A1C1-060B2926F83E]) 
)AS up

WHERE Bool = 'true'
ORDER BY Person, Destination

First of all, I'm not sure why this SELECT NEWID() at the top worked, where I have received errors when trying to SELECT NEWID() before.

I felt a little creative about using statements like AF.AdditionalBoolean19 AS 'BEBD6ED6-AF0A-4A05-A1C1-060B2926F83E' because the table I was inserting into required a GUID from another table that represented a plaintext 'Name'. There is no table linking each column name to that GUID, so I think this was the best way, but I would like to hear if anyone can think of a better way.


Solution

  • A demo how you can unpivot your AdditionalBooleanN columns and rather then doing it row by row just use where clause to filter result and insert into intended destination tables.

    Test Data

    DECLARE @TABLE TABLE 
           (ID INT , dest INT, Person INT, Bol1 INT, Bol2 INT, Bol3 INT)
    INSERT INTO @TABLE VALUES 
    (1 , 100 , 1 , 1 , 1 , 1) ,
    (2 , 200 , 2 , 1 , 1 , 0) ,
    (3 , 300 , 3 , 1 , 0 , 0) ,
    (4 , 400 , 4 , 0 , 0 , 0) 
    

    Query

    -- INSERT INTO Destination_Table (ID , Dest, Person, bol_Column)
    SELECT *                     --<-- Only select columns that needs to be inserted 
    FROM @TABLE t
     UNPIVOT ( Value FOR Bool_Column IN (Bol1, Bol2, Bol3) )up
    -- WHERE  Bool_Column  = ??
    

    Result

    ╔════╦══════╦════════╦═══════╦═════════════╗
    ║ ID ║ dest ║ Person ║ Value ║ Bool_Column ║
    ╠════╬══════╬════════╬═══════╬═════════════╣
    ║  1 ║  100 ║      1 ║     1 ║ Bol1        ║
    ║  1 ║  100 ║      1 ║     1 ║ Bol2        ║
    ║  1 ║  100 ║      1 ║     1 ║ Bol3        ║
    ║  2 ║  200 ║      2 ║     1 ║ Bol1        ║
    ║  2 ║  200 ║      2 ║     1 ║ Bol2        ║
    ║  2 ║  200 ║      2 ║     0 ║ Bol3        ║
    ║  3 ║  300 ║      3 ║     1 ║ Bol1        ║
    ║  3 ║  300 ║      3 ║     0 ║ Bol2        ║
    ║  3 ║  300 ║      3 ║     0 ║ Bol3        ║
    ║  4 ║  400 ║      4 ║     0 ║ Bol1        ║
    ║  4 ║  400 ║      4 ║     0 ║ Bol2        ║
    ║  4 ║  400 ║      4 ║     0 ║ Bol3        ║
    ╚════╩══════╩════════╩═══════╩═════════════╝