SQL - Query Phonenumber that are stored inconsistently

后端 未结 6 1066
既然无缘
既然无缘 2021-01-14 07:10

we a phonenumber field in our database and I would like to do a simple lookup query like:

SELECT * FROM TABLE WHERE Phonenumber = \'555123456\'
相关标签:
6条回答
  • 2021-01-14 07:51

    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

    0 讨论(0)
  • 2021-01-14 07:55

    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).

    0 讨论(0)
  • 2021-01-14 08:00

    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.

    0 讨论(0)
  • 2021-01-14 08:01

    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.

    0 讨论(0)
  • 2021-01-14 08:02

    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.

    0 讨论(0)
  • 2021-01-14 08:06

    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.

    0 讨论(0)
提交回复
热议问题