sql - 重构循环 SQL 插入

标签 sql sql-server database sql-insert

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

我有一个名为 Source 的表,其中 DealerID 是一个非唯一 ID(无论如何在该表中)。对于每个 DealerID,有多个 Name。示例:

15  BillBoard
15  Event
15  Newspaper

16  BillBoard
16  Event
16  Newspaper

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

15  BillBoard
15  Event
15  Newspaper
15  Phone
15  Internet

16  BillBoard
16  Event
16  Newspaper
16  Phone
16  Internet

下面的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

编辑后:

我必须对汤姆的答案制作一个小模组,添加 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)

最佳答案

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)

更正了它以包含 DISTINCT,因为每个 DealerID 都会有多个其他 Name。如果性能存在问题,那么您可以将 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)

关于sql - 重构循环 SQL 插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35297850/

相关文章:

php - 如何比较从数据库中检索的两个数据数组?

c# - 如何使用 C# 在 Sql Server 2008 中存储用户定义的类对象?

sql-server - 基于输入的 SQL Server 日期检查

database - 当多值主键的成员属性是函数依赖的决定因素时,多值主键本身是决定因素吗?

php - sql查询在php中不起作用,根据ID显示相关结果

mysql - SQL - 是否可以替换 uuid 主键中的值?

用于创建范围的 SQL

mysql - 电子商务网站的数据库设计

mysql - 查询计算和临时表

sql-server - SQL Server 的 SET NOEXEC 或 NOPARSE 的 Oracle 等效项是什么?