在SQL中,我有一个EanTbl (EAN varchar(13) (PK), ProductID int)
,其中有数百万条EAN条形码作为字符串。其中许多实际上是相同的,但写的不同,即一个或多个前导。可以将一个ProductID分配给许多EAN条形码编号。 (从历史上看,我会从头开始创建EAN列)
从现在开始,当插入EAN条形码时,我想通过检查现有的EAN是否与新的EAN匹配来避免创建额外的双重条码。
示例EanTbl:
EAN | ProductID
==========================
123456789| 987 \
0123456789| 987 - In reality the same EAN
00123456789| 987 /
现在,当用户输入要我插入例如000123456789
的新值时,我现在希望在T-SQL中可以进行最有效的查询,以发现已经为此ProductID分配了匹配的EAN条形码。
我已经尝试过不同风格的CONVERT(),但你可以想象它的性能很糟糕。这项检查需要在具有50多万行的表格上每分钟发生几百次。
提前感谢您的建议。
答案 0 :(得分:3)
评论太长了。
你应该花时间修理表格。一种方法是将EAN更改为适当的形式。如果你想要一个固定长度的字符串,那么执行以下操作:
select distinct right(replicate('0', 13) + ean, 13) as ean, productid
into #temptable;
truncate table eantbl;
insert into eantbl(ean, productid)
select ean, productid
from #temptable;
如果由于某种原因需要不正确的EAN值,这可能是不可行的。
另一种方法是将规范形式放入表格中。类似的东西:
alter table eantbl add CanonicalEAN char(13);
update eantbl
set CanonicalEAN = right(replicate('0', 13) + ean, 13);
create index idx_eantbl_canonicalean on eantbl(CanonicalEAN);
然后,您可以使用适当的列进行比较,并利用索引。
答案 1 :(得分:1)
添加一个计算列,该列将修剪并以其他方式标准化EAN:
alter table EanTbl add NormalizedEan as (dbo.NormalizeEan([Ean]));
接下来,为此列添加一个索引,您将参加比赛。
答案 2 :(得分:0)
首先可以将它们转换为int
以删除前导零并在插入之前检查该字段。
CAST(CAST([EAN] AS INT) AS VARCHAR(13)) AS [EANfixed]
我主要在这里猜测代码,因为我真的不知道你的表格和字段是什么样的。
答案 3 :(得分:0)
Thanks to the suggestions. In the Long term I will reorganize the table as most of you suggested but for the moment I found the fastest way to do what I want is something like that:
SELECT EanCode, ProductID
FROM EanCodes
WHERE EanCode = @ean
OR EanCode = '0'+@ean
OR EanCode = '00'+@ean
OR EanCode = '000'+@ean
OR EanCode = '0000'+@ean
OR EanCode = '00000'+@ean
OR EanCode = '000000'+@ean
with @ean
being the string parameter of course
It seemed counter-intuitive at first but it is indeed the fastest way.