SQL - 查询存储不一致的Phonenumber

Jan*_*ann 3 sql sql-server sql-server-2005

我们在数据库中有一个phonenumber字段,我想做一个简单的查询查询,如:

SELECT * FROM TABLE WHERE Phonenumber = '555123456'
Run Code Online (Sandbox Code Playgroud)

但由于phonenumbers是由用户输入的并且没有标准化,我们并不真正知道它们的样子.

可能:

  • + 555-123456

要么

  • (555)123 456

要么

  • 555-12-34-56

或者完全不同的东西.

唯一确定的是所有给定的数字应该以正确的顺序存在.是否可以构建一个查询?

Qua*_*noi 5

Oracle:

SELECT  *
FROM    mytable
WHERE   REGEXP_REPLACE(Phonenumber, '[^0-9]', '') = '5551234567'
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

,或者,如果你想看到标准化的电话价值,

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'
Run Code Online (Sandbox Code Playgroud)

但是,您最好为标准化的电话值创建另一列,将其填入触发器并对其进行索引,以便您可以更有效地进行查询.


mar*_*c_s 5

如果您可以更改表(假设它是SQL Server 2005及更高版本),您可以向表中添加计算列,并保留它.此列可以保存"phonenumber"字段的"清理"表示.

像这样的东西:

 create function dbo.CleanPhone(@phone varchar(100))
 returns varchar(100)
 with schemabinding
 as begin
   return
     replace(replace(replace(replace(replace(replace(@phone, ' ', ''), 
             '-', ''), '(', ''), ')', ''), '-', ''), '+', '')
 end
Run Code Online (Sandbox Code Playgroud)

然后:

alter table (yourtable)
 add cleanedPhone as dbo.CleanPhone(Phone) persisted
Run Code Online (Sandbox Code Playgroud)

现在,您的"CleanedPhone"列将始终包含您的电话号码的"清理"版本 - 总是如下:555123456.

由于它是一个PERSISTED字段,因此在查询时不会产生性能损失 - 值创建并存储在表中,并且可作为普通列使用.

在此,您现在可以很容易地查询.


Eri*_*ric 2

由于我不知道你在寻找什么 RDBMS,我将给出最通用的方法:

phonenumber like '%5%5%5%1%2%3%4%5%6%'
Run Code Online (Sandbox Code Playgroud)

这假设所有电话号码至少具有相同的长度(以数字为单位)。