we a phonenumber field in our database and I would like to do a simple lookup query like:
SELECT * FROM TABLE WHERE Phonenumber = \'555123456\'
IF you can alter the table (assuming it's SQL Server 2005 and up), you could add a computed column to your table, and persist it. This column could hold a "cleaned up" representation of your "phonenumber" field.
Something like this:
create function dbo.CleanPhone(@phone varchar(100))
returns varchar(100)
with schemabinding
as begin
return
replace(replace(replace(replace(replace(replace(@phone, ' ', ''),
'-', ''), '(', ''), ')', ''), '-', ''), '+', '')
end
and then:
alter table (yourtable)
add cleanedPhone as dbo.CleanPhone(Phone) persisted
Now, your "CleanedPhone" column would always contained a "cleaned up" version of your phone number - always something like: 555123456.
Since it's a PERSISTED field, you don't incur a performance penalty when querying, either - the value is created and stored in your table, and is available as a normal column.
On this, you could now query quite easily.
Marc
Since I don't know what RDBMS you're looking for, I'll give the most generic way:
phonenumber like '%5%5%5%1%2%3%4%5%6%'
This assumes that all phone numbers are at least equal length (in digits).
You can try something like:
SELECT * FROM TABLE WHERE
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(phone,'(','')
,')','')
,'-','')
,'+','')
,' ','') = '0398765432'
Replace any non numeric value with an empty string.
I took @Eric's concept and using a bit of PHP code this will work with any phone number input. (Assuming $_GET has the phone number input)
$phone = $_GET['phone'];
$phone_formatted = "%";
for ($i=0; $i<strlen($phone); $i++) {
$phone_formatted .= ($phone[$i] . "%");
}
This will result in a $phone_formatted value that looks like '%x%x%x%x%x%x%x%x%x%', where x are arbitary numbers.
Now you can use the sql query:
phonenumber like $phone_formatted
If you input 1231231234, it will match variations like 123-123-1234, (123) 123-1234 and so on.
If you want to take this a step further you could also strip all non-numeric characters (to remove the parentheses, dashes, and spaces) from the $_GET['phone'] value, so that inputs like (123) 123-1234 will also match all of the above cases.
ALternatively, you could fix your data entry pages to strip all nonnumeric characters before entry into the database and then fix all existing data to strip the numbers. Then put a constraint on the field that requires all characters to be numeric. Then you don't need to keep looking for nonnumeric characters every time you want to display a phone number and you can easily have the user interface consistently show them in whatever format you prefer them to be shown in. Where possible, fixing the problem (ie that you didn't put proper controls in your user interface) is better than creating workarounds which will usually create performance slowdowns for no good reason.
In Oracle
:
SELECT *
FROM mytable
WHERE REGEXP_REPLACE(Phonenumber, '[^0-9]', '') = '5551234567'
In SQL Server 2005+
:
WITH digits AS
(
SELECT 1 AS digit
UNION ALL
SELECT digit + 1
FROM digits
WHERE digit <= 100
)
SELECT *
FROM mytable
WHERE (
SELECT SUBSTRING(number, digit, 1) AS [text()]
FROM digits
WHERE SUBSTRING(number, digit, 1) BETWEEN '0' AND '9'
FOR XML PATH('')
) = '5551234567'
, or, if you want to see the normalized phone value,
WITH digits AS
(
SELECT 1 AS digit
UNION ALL
SELECT digit + 1
FROM digits
WHERE digit <= 100
),
phones AS
(
SELECT m.*,
(
SELECT SUBSTRING(number, digit, 1) AS [text()]
FROM digits
WHERE SUBSTRING(number, digit, 1) BETWEEN '0' AND '9'
FOR XML PATH('')
) AS nphone
FROM mytable m
)
SELECT *
FROM phones
WHERE nphone = '5551234567'
However, you better create another column for normalized phone values, fill it in a trigger and index it, so you can query more efficiently.