views:

101

answers:

5

Hi, Is it possible to write a WHERE condition in MS SQL Server that will grab rows that:

  • begin with a specified letter
  • then have a decimal
  • then anything else

I basically have a table that contains postcodes and I want all postcodes that belong to Birmingham - B followed by a number. Some postcodes are in there that start B and then another letter which do not belong to Birmingham, so I can't simply useLIKE 'B%'.

Thanks!

+7  A: 

Use LIKE 'B[0-9]%'. The "[0-9]" indicates any character in the range '0'-'9'.

Also bear in mind that (a) someone will have typed in an "O" instead of a "0" in some cases, and that there may be some international postcodes that also start with B and a number, so if you've got a reliable country field, you should check that, too :) Yes, I work with postcodes a lot :)

Matt Gibson
Birmingham, like most areas, doesn't have a '0' district, so 'B[1-9]%' would be more accurate (if a trifle pedantic). http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom
Mike Woodhouse
@Mike Fair point! Although I notice in the database I have to hand, there are allegedly four "B0..." addresses in Birmingham, where I guess the users meant to type "B1...", so one may need to adjust one's pedantry levels depending on which particular errors need to be included :)
Matt Gibson
Using the data in the Ordnance Survey's Open Codepoint files, you could validate whether the postcode actually existed rather than simple validation on the formatting
Mark Baker
Indeed, Open Codepoint is a lovely, and relatively recently-released resource, so it's definitely worth mentioning. You could then fairly easily geocode all your (valid) postcodes and have a query like "within ten miles of Birmingham City Centre" using Haversine, say. But it gets more complicated the odder your data is, with things like half-postcodes, or with stuff in the Channel Islands (which I believe are postcoded but aren't geocoded in Open Codepoint, last time I looked.)
Matt Gibson
A: 

I think you can do something like this:

Select * From PostCodes
Where PostCode Like 'B[0-9]%'
Barry
That will match a B, followed by any bunch of characters, followed by a number, followed by any bunch of characters, so I think it will match, for example, "BS1 6DF", a Bristol postcode, as well as the Birmingham postcodes.
Matt Gibson
@Matt - As soon as I posted I noticed a rogue % in there so I amended my answer straight away. Cheers
Barry
A: 
SELECT postc FROM postcodes WHERE postc LIKE 'B[0-9]*%';

Something along these lines!

You could also do:

SELECT
    postc as ps,UPPER(SUBSTR(ps),1,1) as firstLetter,SUBSTR(ps,2,1) as secondNumber
FROM
    postcodes
WHERE
    firstLetter = 'B' AND secondNumber LIKE '[0-9]%'

Something along them lines.

RobertPitt
-1 SQL doesn't work like that. Your LIKE predicate seems to contain two wildcard characters. The `firstletter` column correlation name in the `SELECT` clause cannot be used in `WHERE` clause.
onedaywhen
A: 

MySQL has regular expressions (REGEXP/RLIKE) built in. I think that you could add the functionality to others, such as SQL Server.

This would give you more precision, e.g.

SELECT * FROM PostCodes WHERE PostCode RLIKE '^B[[:digit:]]{1,2}[:space:]'

This would also allow better matching of possible typos in the condition.

Cez
+2  A: 

According to the Wikipedia article on the B postcode area:

  • B39 is invalid
  • B95 is Henley-in-Arden,
    Stratford-on-Avon -- would you
    consider Henley-in-Arden to "belong
    to Birmingham"? (maybe it is, I really don't know)

Perhaps safest to expand out the codes you consider to be Birmingham:

postcode LIKE 'B1 %'
OR postcode LIKE 'B2 %'
OR postcode LIKE 'B3 %'
...
OR postcode LIKE 'B10 %'
OR postcode LIKE 'B11 %'
OR postcode LIKE 'B12 %'
...

Those prefixes could of course be stored in a table.

onedaywhen