在Table2中为Table1的每列插入一个新行

时间:2016-06-03 20:07:57

标签: sql-server tsql sql-insert

给出以下表格布局和数据行:

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


1   NULL            800-222-2222    800-333-3333    800-444-4444
2   e@email.com     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   e@email.com
5   2   800-555-5555
6   2   800-777-7777
7   2   800-888-8888

大图,我想为INSERT中的每一行重复Table1。弄清楚如何在至少一行中完成这项工作将是一个很好的起点。

5 个答案:

答案 0 :(得分:1)

CROSS APPLYUNPIVOT可用于此任务:

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来存储将插入的值类型:电子邮件,电话号码或传真号码。

答案 1 :(得分: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

如果您希望代码看起来更清洁,请使用cte或table变量:

; 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

答案 2 :(得分: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

答案 3 :(得分:0)

Union非常适合此目的。我建议将valType字段添加到table2。

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.

答案 4 :(得分:0)

对于你想要的每个字段,我可以想到一个相当简单的方法来使用不同的INSERT语句:

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

EmailAddress替换为Table1中每个语句的另一个列名,并且应该只提取列不为null的所有列。或者,您可以在所有UNION语句中使用SELECT一次完成所有操作。