重构循环SQL插入

Cas*_*ton 2 sql database sql-server sql-insert

此插入语句有效.但是,我希望也许有人可以教我一种更有效的方法来进行这种查询.这就是我所拥有的......

我有一个名为Source的表,其中DealerID是一个非唯一的ID(无论如何都在这个表中).对于每个DealerID,有多个名称.例:

15  BillBoard
15  Event
15  Newspaper

16  BillBoard
16  Event
16  Newspaper
Run Code Online (Sandbox Code Playgroud)

我知道我知道.这是存储此数据的非常低效的方法.我们正在处理遗留应用程序,我现在无法彻底改变这种数据结构.所以,我需要做的是为每个DealerID添加两个新记录.一个用于"电话",一个用于"互联网".所以在插入之后,它看起来像这样:

15  BillBoard
15  Event
15  Newspaper
15  Phone
15  Internet

16  BillBoard
16  Event
16  Newspaper
16  Phone
16  Internet
Run Code Online (Sandbox Code Playgroud)

下面的sql语句有效,但我想知道是否有更好的方法...

declare @SourceTemp table (
   [Id] int identity (1, 1) not null,
   [DealerId] int
)

insert into @SourceTemp select distinct DealerId from Source where DealerId is not null

declare @dealerid int
declare @rowcount int = 1
declare @idcount int
select @idcount = max(Id) from  @SourceTemp

while @rowcount < (@idcount + 1)
begin
    select @dealerid = DealerId from @SourceTemp where Id = @rowcount

    ---------------- Insert Phone
    if not exists (select * from Source where DealerId = @dealerid and Name = 'Phone')
    begin
        insert into 
        Source 
            ([DealerID],[Name],[Service],[CampaignCode],[Description],[Created],[UserCreated],[Active])
        values
            (@dealerid, 'Phone', 'Generic', 'CampaignCode', NULL, GETDATE(), 0, 1)
    end

    --------------- Insert Internet
    if not exists (select * from Source where DealerId = @dealerid and Name = 'Internet')
    begin
        insert into 
        Source 
            ([DealerID],[Name],[Service],[CampaignCode],[Description],[Created],[UserCreated],[Active])
        values
            (@dealerid, 'Internet', 'Generic', 'CampaignCode', NULL, GETDATE(), 0, 1)
    end

    set @rowcount = @rowcount + 1
end
Run Code Online (Sandbox Code Playgroud)

编辑后:

我不得不为汤姆做出一个小模型,添加了DISTINCT.这有效......

INSERT INTO Source ([DealerID], [Name], [Service], [CampaignCode], [Description], [Created], [UserCreated], [Active])
SELECT DISTINCT
    S.DealerId, SQ.Name, 'Generic', 'CampaignCode', NULL, GETDATE(), 0, 1
FROM
    Source S
CROSS JOIN (SELECT 'Internet' AS Name UNION ALL SELECT 'Phone' AS Name) SQ
WHERE
    NOT EXISTS (SELECT * FROM Source WHERE DealerID = S.DealerID AND Name = SQ.Name)
Run Code Online (Sandbox Code Playgroud)

Tom*_*m H 5

INSERT INTO Source (DealerID, Name, Service, CampaignCode, Description, ...)
SELECT DISTINCT
    S.DealerID, SQ.Name, ...
FROM
    Source S
CROSS JOIN (SELECT 'Internet' AS Name UNION ALL SELECT 'Phone' AS Name) SQ
WHERE
    NOT EXISTS (SELECT * FROM Source WHERE DealerID = S.DealerID AND Name = SQ.Name)
Run Code Online (Sandbox Code Playgroud)

修正了它包含DISTINCT,因为Name每个DealerID都有多个其他的.如果性能是一个问题,那么您可以DISTINCT向下移动到Source表上的子查询,然后CROSS JOIN从那里:

INSERT INTO Source (DealerID, Name, Service, CampaignCode, Description, ...)
SELECT DISTINCT
    S.DealerID, SQ.Name, ...
FROM
    (SELECT DISTINCT DealerID
     FROM Source
    ) S
CROSS JOIN (SELECT 'Internet' AS Name UNION ALL SELECT 'Phone' AS Name) SQ
WHERE
    NOT EXISTS (SELECT * FROM Source WHERE DealerID = S.DealerID AND Name = SQ.Name)
Run Code Online (Sandbox Code Playgroud)