August 31, 2006 at 6:32 pm
My situation is this.
I need to check a table to see if a partnumber (varchar) exists in it. That's easy! But what if the value has two characters transposed?
It appears to me that SOUNDEX and DIFFERENCE completely ignore numbers.
I.E.
select soundex('1644700809a'), soundex('5xreww332')
will return '0000', '0000'
-and-
select difference('1644700809', '1644708009')
will return 4 (when they are actually similar)
If anyone can point me in the right direction I would really appreciate it.
______________________________________________________________________
Personal Motto: Why push the envelope when you can just open it?
If you follow the direction given HERE[/url] you'll likely increase the number and quality of responses you get to your question.
Jason L. SelburgSeptember 1, 2006 at 2:39 am
Talk about time...This might be a step in the right direction for you...just posted yesterday.
September 1, 2006 at 6:31 am
I think this is a better approach for this task. But you are right otherwise Andrew!
DECLARE @Search VARCHAR(10),
@MaxDigitsWrong TINYINT
SELECT @Search = '1644705509',
@MaxDigitsWrong = 2
DECLARE @Test TABLE (PartNo VARCHAR(10))
INSERT @Test
SELECT '1644700809' UNION ALL
SELECT '1644700808' UNION ALL
SELECT '1644708509'
SELECT x.PartNo
FROM (
SELECT t.PartNo,
n.Number,
SUBSTRING(PartNo, n.Number, 1) c
FROM @Test t
CROSS JOIN (
SELECT DISTINCT Number
FROM master..spt_values
WHERE Number BETWEEN 1 AND 10
) n
) x
INNER JOIN (
SELECT DISTINCT Number,
SUBSTRING(@Search, Number, 1) c
FROM master..spt_values
WHERE Number BETWEEN 1 AND 10
) s ON s.Number = x.Number
GROUP BY x.PartNo
HAVING SUM(CASE WHEN x.c = s.c THEN 0 ELSE 1 END) <= @MaxDigitsWrong
N 56°04'39.16"
E 12°55'05.25"
September 1, 2006 at 7:14 am
You can also use the Levesthein Edit Distance algorithm found here
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=51540
N 56°04'39.16"
E 12°55'05.25"
September 1, 2006 at 11:42 am
"...WHERE Number BETWEEN 1 AND 10"
Why not?
"...WHERE Number BETWEEN 0 AND 9"
September 1, 2006 at 12:04 pm
Peter, THANK YOU for the help. Your first solution works partially, but it would incorrectly not match '12345' to 'a12345'. And I altered the spt_values to handle varying lengths of part numbers.
I REALLY appreciate the help. The link helped as well and I think I'm on the right track now!
If you're curious, here's my adapted solution:
declare @partnoLength int
set @partnoLength = len(@partno)
SELECT
DISTINCT
x.reportablepartid,
x.partdesc,
x.partnumber
FROM
(
SELECT t.reportablepartid, t.partnumber, t.partdesc, n.Number, SUBSTRING(partnumber, n.Number, 1) c
FROM reportableparttable t
CROSS JOIN
(
SELECT DISTINCT Number
FROM master..spt_values
WHERE Number BETWEEN 1 AND @partnoLength
) n
WHERE t.jobid = @jobid
) x
INNER JOIN
(
SELECT DISTINCT Number, SUBSTRING(@partno, Number, 1) c
FROM master..spt_values
WHERE Number BETWEEN 1 AND @partnoLength
) s ON s.Number = x.Number
GROUP BY x.reportablepartid, x.partnumber, x.partdesc
HAVING
SUM(CASE WHEN x.c = s.c THEN 0 ELSE 1 END) <= @maxPartDifference
UNION
SELECT
x.reportablepartid,
x.partdesc,
x.partnumber
FROM
(
SELECT t.reportablepartid, t.partnumber, t.partdesc, n.Number, SUBSTRING(reverse(partnumber), n.Number, 1) c
FROM reportableparttable t
CROSS JOIN
(
SELECT DISTINCT Number
FROM master..spt_values
WHERE Number BETWEEN 1 AND @partnoLength
) n
WHERE t.jobid = @jobid
) x
INNER JOIN
(
SELECT DISTINCT Number, SUBSTRING(reverse(@partno), Number, 1) c
FROM master..spt_values
WHERE Number BETWEEN 1 AND @partnoLength
) s ON s.Number = x.Number
GROUP BY x.reportablepartid, x.partnumber, x.partdesc
HAVING
SUM(CASE WHEN x.c = s.c THEN 0 ELSE 1 END) <= @maxPartDifference
______________________________________________________________________
Personal Motto: Why push the envelope when you can just open it?
If you follow the direction given HERE[/url] you'll likely increase the number and quality of responses you get to your question.
Jason L. SelburgViewing 6 posts - 1 through 5 (of 5 total)
You must be logged in to reply to this topic. Login to reply