【发布时间】:2018-07-19 16:22:27
【问题描述】:
首先,我想为您即将遇到的混乱代码道歉,但这对我的观点很重要。我已经稍微简化了它,但这里通常是我正在使用的代码:
create table [TableExample](
ID varchar(50) primary key not null,
);
with CTE as (
select case when ltrim(rtrim(S1.ID)) is null
then convert(varchar(50),newid())
else ltrim(rtrim(S1.ID))
end as 'ID',
row_number()over(partition by ltrim(rtrim(S1.ID)) order by newid()) as 'duplicates'
from [DB2].[dbo].[Source1] as S1
full outer join [DB2].[dbo].[Source2] as S2
on S2.[ID]=S1.[ID]
full outer join [DB2].[dbo].[Source3] as S3
on S3.[ID]=S1.[ID])
insert into [dbo].[TableExample] (
[ID]
)
select distinct case
when [duplicates] > 1
then convert(varchar(50),newid())
else CTE.[ID]
end as 'ID'
from [DB2].[dbo].[Source1] as S1
full outer join [DB2].[dbo].[Source2] as S2
on ltrim(rtrim(S2.ID))=ltrim(rtrim(S1.ID))
full outer join [DB2].[dbo].[Source3] as S3
on ltrim(rtrim(S3.ID))=ltrim(rtrim(S1.ID))
full outer join CTE on CTE.ID=ltrim(rtrim(S1.ID))
where (S2.ID is not null or S3.ID is not null or S1.ID is not null)
and [duplicates] = 1
如您所见,我正在运行多个非常冗余的检查,以确保主键字段 [ID] 没有收到任何重复项。我选择 distinct,使用 CTE 标记任何重复的键然后拒绝它们,最后如果仍然通过,我将重复项更改为
convert(varchar(50),newid())
然而,每次我运行它时都会遇到重复键错误。
如果您想知道,是的,我每次都会删除表格,以确保没有保留任何可能导致错误的内容。
有超过 100,000 行数据需要输入,我对这件事束手无策。任何建议将不胜感激!
【问题讨论】:
-
您能否提供表 Source1、Source2 和 Source3 的示例数据,并说明您要查找哪些重复项?令人困惑的部分是,在 CTE 中,Source2 和 Source3 已连接,但未使用。重复项是否分布在这些表中?您可能需要联合而不是联接。
-
错误消息标识重复值。所以删除插入语句,只需对提到的 ID 值运行选择查询。而且你的逻辑很密集,正如所写的那样,没有什么意义。您是否假设每个表中的 ID 都是唯一的? CTE 和实际 select 语句中完全连接的重复很难理解 - 不一致的连接逻辑使情况变得更糟。很少有人需要修剪字符串以进行连接,但如果你这样做了,那你为什么不在 cte 中修剪呢?
标签: sql sql-server key