2010-02-05 19 views
3

我有一种情况,即传入的数据值可能有或没有前导零。我需要将它匹配到SQL Server表中的字段/行。 SQL Server数据库中的字段值可能也可能不具有前导零。在SQL Server表中匹配具有可变数量前导零的字段

所以,我可能有:

  • 传入= 5042800138
    和分贝值可以是任何5042800138,05042800138,005042800138,0005042800138

  • 或传入的可能是005042800138
    和db中的值可以是5042800138,05042800138,005042800138,0005042800138中的任何一个

我想出了解决的办法是去掉前导零(总是)上输入数据,并使用SQL像下面的例子:

-- this simulates the incoming value to check 
-- i strip out the leading zeroes. 
declare @tryUPC as varchar(40) 
set @tryUPC = '5042800138' 

-- try to find it in the database and ignore leading zeroes 
select prod_uid, prod_partno, prod_upc 
from products as p 
where (prod_upc = @tryUPC) or 
    (
    len(prod_upc) > len(@tryUPC) 
    and right(prod_upc, len(@tryUPC)) = @tryUPC 
    and stuff(prod_upc, 1, len(prod_upc) - len(@tryUPC), '0') = prod_upc 
    ) 

这似乎是工作。我的问题是,我错过了什么? SQL Server是否有更好的方式来处理这个问题?我使用SQL Server 2005的

TIA,

+0

看到我的编辑,它显示了你如何使用索引 – 2010-02-05 19:13:51

回答

2

如果你不能改变现有的数据剥去前导零/转换为INT,它可能会更快,只是做一些事情,像这样:

WHERE prod_upc IN (@tryUPC, '0' + @tryUPC, '00' + @tryUPC, '000' + @tryUPC [...]) 

这就像我的脚一样优雅,但它会更加静态,并且(可能)更有可能获得任何相关索引。

这是假设您有多少前导零有一个有限的限制,介意。将数据转换为INT(或添加新的INT列并在插入时计算它)可能是解决此问题的最佳解决方案。

+0

我想这可能会更好。我必须看看允许的前导零数。为了使它处理如此之多的零可能是没有必要的。谢谢 – 2010-02-05 19:10:45

+0

只要数据不分段,我肯定会推荐这个(分段含义)。或者,你可以填充所有的特定数量的零(123-> 00123,0123-> 00123,00123-> 00123等)。如上所述,密钥是你正在比较的两者之间的一致性。 – KSimons 2010-02-05 19:17:28

0

1)更新所有的现有数据不具有任何前导零,可能使用BIGINT数据类型
2)总是从剥离前导零保存和搜索前的输入
3)再也不用担心引导零,而且你实际上可以使用索引!

编辑 后OP的评论:

就不是很好,但它不是现实。我想我应该提到这是一个传统的应用程序。 upc代码可以输入到一堆不同的地方。改变数据类型将需要大规模的重构。此外,有时需要零 - 数据库有一个很好的理由。 - 唐·迪金森

你可以使用一个持久的计算列,其中你REVERSE()列,然后索引它。然后,您可以查询:

WHERE Column1Reverse Like REVERSE('1234567')+'%' --can use the persistent computed column's index 

添加一个持久化计算列(即反转字符串)和指数就可以了,使用此代码:

ALTER TABLE YourTable ADD ReversedYourString反向(YourString)坚持

CREATE NONCLUSTERED INDEX IX_YourTable_ReversedYourString 
ON YourTable (ReversedYourString) 
+0

+1 - 击败了我。我所建议的一切也是为了将数据转化为理想/最佳格式来查询 – AdaTheDev 2010-02-05 18:37:10

+0

@AdaTheDev忘了一个:......将数据转化为理想/最优/ **一致**格式...... – 2010-02-05 18:39:38

+0

@KM - 是的!一致性是冠军:) – AdaTheDev 2010-02-05 18:48:52

4

只是另一个倾向(纠正数据将是最好的,但接受的答案也是一个体面的解决方法):添加一个持久的索引计算列“actualUPC”,是一个字符类型,用正确数量的前导零计算。例如:

如果“真实”代码被认为是12位数字,使象

right('000000000000' + originalColumn, 12) 

这样实际上对输入数据进行校正计算列,然后索引正确,并且可以与索引进行搜索。

当您查询时,还会填充输入以匹配,作为查询中的常量。

检查对索引计算列的限制,但是在太疯狂之前。这样的BTW代码(邮政编码,序列号,ssn's等)总是应该以文本数据存储,前导零,而不能作为整数或数字类型存储。从一个在邮政编码01033长大的男人身上拿走它。

相关问题