Inserting two rows from single row
As Aaron mentioned, for some reason you need to terminate each statement in Fiddle.
Anyway, for the query, you can use CROSS APPLY
to expand the result set. This method scans the base table only once, and for each row applies the subquery, which in this case actually selects two rows:
INSERT INTO userContact(userId, contactType, contactInfo)
SELECT
ui.userId,
c.contactType,
c.contactInfo
FROM usersToImport ui
CROSS APPLY
(
SELECT 'email' AS contactType, ui.email AS contactInfo UNION ALL
SELECT 'telephone', ui.telephone
) c;
A few other ways to do it, no real difference in performance even when I scaled up to 1 million rows:
INSERT userContact ( userId, contactType, contactInfo )
SELECT u.userId, x.contactType, x.contactInfo
FROM usersToImport u
CROSS APPLY (
VALUES
( 'email', email ),
( 'telephone', telephone )
) x ( contactType, contactInfo )
INSERT userContact ( userId, contactType, contactInfo )
SELECT userId, contactType, contactInfo
FROM
(
SELECT userId, email, CAST( telephone AS VARCHAR(200) ) telephone
FROM usersToImport
) u
UNPIVOT ( contactInfo FOR contactType In ([email], [telephone]) ) upvt
There is nothing wrong with your code, you just forgot to use semi-colons to terminate your statements.
The following works just fine:
insert userContact
select userId,
'email',
email
from usersToImport
union all
select userId,
'telephone',
telephone
from usersToImport;
------------------^
select * from usersToImport;
---------------------------^
select * from userContact;
-------------------------^
And to be quite honest, I don't think you'll find a more efficient way to turn 5 rows into 10.