Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Number Within A Range (as text!)

Author  Topic 

samtoffa
Yak Posting Veteran

60 Posts

Posted - 2004-08-11 : 11:12:22
In one of my tables I have a field that represents building numbers stored as text. These are single building numbers e.g. 1,56,28 or more complex ranges for big buildings e.g. 16-18 etc. In a seperate table I have a business address e.g. 23. Is there a reasonably simple way to build a function that returns true if the address is in the range. E.g. 23 in the business address table and 18-25, or 23 in the range table?
To make things more compliacted sometimes the address range fields have more than one building e.g. 16-18, 345-349 but I think I can cope with this if someone can point me in the right direction for the above.
My instinct is to cleave the numbers from the right and left of the '-' sign, convert to numeric and see if my test value is between or equal to the split values. Anyone got a better idea?!! And yes, the data should never have been entered in this way in the first place...blame the UK National Health Service!
Cheers,
Sam

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2004-08-11 : 11:19:29
I would say you are probably right (about splitting on '-'), and I'm sure it can done.

Beyond that...why don't you give us a little sample (tables and data), and we might be able to give you something a little more specific.

Corey
Go to Top of Page

samtoffa
Yak Posting Veteran

60 Posts

Posted - 2004-08-11 : 11:34:28
Table 1 (in part)
Hospital Name | Number
St Marks........| 29
Queen Mary....| 1023
Morrfields.......| 6

Table 2 (in part)
Postal Addresses | Street
3,7,8-12,18-32...| Whitely Street
1020-1028.........| Park Crescent
9......................| Old Street South

Rows 1 and 2 should return True and Row 3 false
Go to Top of Page

DustinMichaels
Constraint Violating Yak Guru

464 Posts

Posted - 2004-08-11 : 11:43:21
Is there anyway you could normalize this part of the database?
If not your best bet is to probably use a User Defined Function (UDF) that would split strings to do the search.

But if you could normalize the database you could have a BuildingNumbers table that would include a column for the starting number and a column for the ending number. For the cases where there is a single building number the start number and end number would be the same.

This way when you run your query you could use a BETWEEN clause between the start and ending building numbers.

Dustin Michaels
Go to Top of Page

samtoffa
Yak Posting Veteran

60 Posts

Posted - 2004-08-11 : 11:49:42
Your idea was my first instinct Dustin. However the ranges come from a Postcode (zipcode) table with more than 2.5 Million rows!! I think a table with individual numbers and 'start number' 'end number' fields could make this number increase closer to 10 Million.
Someone should have thought of this when they designed this database!
Sam
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2004-08-11 : 11:53:20
try this:


declare @matches table (id1 int, id2 int)

Declare @table1 table
(
id int identity(1,1) not null,
HospitalName varchar(100),
Number int
)
Insert Into @table1 Values ('St Marks',29)
Insert Into @table1 Values ('Queen Mary',1023)
Insert Into @table1 Values ('Morrfields',6)

Declare @table2 table
(
id int identity(1,1) not null,
range varchar(100),
Street varchar(100)
)
Insert Into @table2 Values ('3,7,8-12,18-22','Whitely Street')
Insert Into @table2 Values ('1020-1028','Park Crescent')
Insert Into @table2 Values ('9','Old Street South')

Select * From @table1
Select * From @table2

While exists(Select * From @table2 where range like '%,%')
Begin
Insert Into @matches
Select A.id, Z.id
From @table1 as A
Inner Join
(
Select
id,
lEnd = case when charindex('-',range)>0 then convert(int,left(range,charindex('-',range)-1)) else convert(int,range) end,
hEnd = case when charindex('-',range)>0 then convert(int,reverse(left(reverse(range),charindex('-',reverse(range))-1))) else convert(int,range) end
From
(
Select id, range = left(range,charindex(',',range)-1) From @table2 where range like '%,%'
) as A
) as Z
On A.number between Z.lEnd and Z.hEnd

Update @table2
Set
range = right(range,len(Range)-charindex(',',range))
From @table2
where range like '%,%'
End

Insert Into @matches
Select A.id, Z.id
From @table1 as A
Inner Join
(
Select
id,
lEnd = case when charindex('-',range)>0 then convert(int,left(range,charindex('-',range)-1)) else convert(int,range) end,
hEnd = case when charindex('-',range)>0 then convert(int,reverse(left(reverse(range),charindex('-',reverse(range))-1))) else convert(int,range) end
From @table2
) as Z
On A.number between Z.lEnd and Z.hEnd


Select B.*, C.*
From @matches as A
Inner Join @table1 as B
On A.id1 = B.id
Inner Join @table2 as C
On A.id2 = C.id


Corey
Go to Top of Page

samtoffa
Yak Posting Veteran

60 Posts

Posted - 2004-08-11 : 12:24:00
Thanks Corey,
this seems to be taking me in the direction that I need to go. I'm slightly worried about how much coffee you must drink to come up with something so complex in such a short space of time!!!
Many thanks, I'll do my best to get it to work for me.
Sam
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2004-08-11 : 13:06:00
quote:

However the ranges come from a Postcode (zipcode) table with more than 2.5 Million rows!! I think a table with individual numbers and 'start number' 'end number' fields could make this number increase closer to 10 Million.



this is all the more reason to normalize your data properly. Searching 10 million rows using indexes in a normalized table will probably be (literally) hundreds of times faster than searching 2.5 million rows w/o any indexes and doing text comparisons and parsing.


- Jeff
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2004-08-11 : 13:06:13
it was about lunch time and people were rushing me...
what can i say

EDIT:For the record I agree with Jeff on the storage method... it would be significantly faster. Good luck with it though!

Corey
Go to Top of Page

samtoffa
Yak Posting Veteran

60 Posts

Posted - 2004-08-11 : 18:14:48
Point taken! Thanks all for your help. I'll do some re-designing.
Cheers,
Sam
Go to Top of Page
   

- Advertisement -