2016-06-03 4 views
0

Учитывая следующие сервировки и данные строки:Вставьте новую строку в Table2 для каждого столбца Table1

SELECT [Id] 
     ,[EmailAddress] 
     ,[PhoneNumber1] 
     ,[PhoneNumber2] 
     ,[FaxNumber] 
FROM [Database].[dbo].[Table1] 


1 NULL   800-222-2222 800-333-3333 800-444-4444 
2 [email protected]  800-555-5555 800-777-7777 800-888-8888 

Я ищу, чтобы вставить новую строку для каждого столбца, который не является нулевым в следующей таблицу макет:

SELECT [Id] 
     ,[FkId] 
     ,[Value] 
FROM [Database].[dbo].[Table2] 

Вот пример того, что я считаю желаемым выходом.

1 1 800-222-2222 
2 1 800-333-3333 
3 1 800-444-4444 
4 2 [email protected] 
5 2 800-555-5555 
6 2 800-777-7777 
7 2 800-888-8888 

Большая картина, я ищу, чтобы повторить эту INSERT для каждой строки в Table1. Выяснить, как это сделать, как минимум, в одной строке, будет хорошей отправной точкой.

+1

Вы желаете сделать это, используя только SQL заявления? – Brice

+0

@Brice да, это предпочтительнее. Есть ли альтернатива? – HappyCoding

+0

Ну, вы могли бы сделать это, используя цикл в каком-то скрипте, если вы уже каким-то образом манипулируете данными с помощью кода, или можете написать инструкцию SQL, которая это сделает. Кажется, что существует тысяча способов сделать одно, просто желая узнать, каковы ваши потребности. – Brice

ответ

1

Используйте Union заявление, чтобы получить один набор данных, и это так же просто, как вставить заявление:

Insert Into Table2 
Select Id, EmailAddress From Table1 
Where EmailAddress Is Not Null And EmailAddress <> '' 
    Union All 
Select Id, PhoneNumber1 From Table1 
Where PhoneNumber1 Is Not Null And PhoneNumber1 <> '' 
    Union All 
Select Id, PhoneNumber2 From Table1 
Where PhoneNumber2 Is Not Null And PhoneNumber2 <> '' 
    Union All 
Select Id, FaxNumber From Table1 
Where FaxNumber Is Not Null And FaxNumber <> '' 
Order By Id 

Или использовать КТР или табличную переменную, если вы хотите, чтобы код выглядеть немного очистителя:

; With tempCte As (
    Select Id, EmailAddress As Value From Table1 Union All 
    Select Id, PhoneNumber1 As Value From Table1 Union All 
    Select Id, PhoneNumber2 As Value From Table1 Union All 
    Select Id, FaxNumber As Value From Table1 
) 
Insert Into Table2 
Select Id, Value From tempCte 
Where Value Is Not null 
Order By Id 
0

Union отлично подходит для этой цели. Я бы рекомендовал добавить поле valType в таблицу2.

insert table2(fkid,value,valType) 
select id,email, 'email' 
from table1 where email is not null 
union 
select id,phone1, 'phone1' 
from table1 where phone1 is not null 
--repeat union for other values. 
1

CROSS APPLY или UNPIVOT могут быть использованы для решения этой задачи:

INSERT INTO dbo.Table2 (FkID, [Value]/*, [ValueType]*/) 
SELECT x.ID, x.[Value] /*, x.[ValueType]*/ 
FROM dbo.Table1 a 
CROSS APPLY (
    SELECT a.EmailAddress, 'E' WHERE a.EmailAddress IS NOT NULL AND a.EmailAddress <> '' 
    UNION ALL 
    SELECT a.PhoneNumber1, 'P' WHERE a.PhoneNumber1 IS NOT NULL AND a.PhoneNumber1 <> '' 
    UNION ALL 
    SELECT a.PhoneNumber2, 'P' WHERE a.PhoneNumber2 IS NOT NULL AND a.PhoneNumber2 <> '' 
    UNION ALL 
    SELECT a.FaxNumber, 'F' WHERE a.FaxNumber IS NOT NULL AND a.FaxNumber <> '' 
) x ([Value], [ValueType]) -- [ValueType] = E[email], P[honeNumber], F[axNumber] 
WHERE NOT EXISTS (
    SELECT * FROM dbo.Table2 b 
    WHERE b.FkID = a.ID 
    AND b.[Value] = x.[Value] 
    --AND b.[ValueType] = x.[ValueType] 
) 

Примечание: Как вы можете видеть, я добавил новый столбец ValueType для хранения также, какие значения будут вставлены: сообщения электронной почты, Номера телефонов или номера факсов.

+0

Примечание: для 'dbo.Table1' будет хорошо иметь индекс UNIQUE на FkID + Value/*, ValueType */ –

+0

Второе примечание: это сканирует' dbo.Table1' только один раз. –

0

я могу думать о довольно простой способ сделать это с помощью другого INSERT заявление для каждого поля вы хотите:

INSERT INTO Table2 (FkId, Value) 
    SELECT Id, EmailAddress FROM Table1 
    WHERE EmailAddress IS NOT NULL; 

Заменить EmailAddress с другим именем столбца от Table1 для каждого оператора, и это должно просто потянуть все столбцы, где столбец не равен нулю. Или вы можете использовать UNION во всех операциях SELECT, чтобы сделать все сразу.

1

Вот быстрый кусок кода, чтобы сделать это с помощью UNPIVOT

INSERT INTO Table2 
SELECT 
    u.Id, 
    u.Type, 
    u.Value 
FROM Table1 as t 
UNPIVOT 
(value for Type in (EmailAddress, Phone1, Phone2, FaxNumber)) 
as u