Jan*_*ann 3 sql sql-server sql-server-2005
我们在数据库中有一个phonenumber字段,我想做一个简单的查询查询,如:
SELECT * FROM TABLE WHERE Phonenumber = '555123456'
Run Code Online (Sandbox Code Playgroud)
但由于phonenumbers是由用户输入的并且没有标准化,我们并不真正知道它们的样子.
可能:
要么
要么
或者完全不同的东西.
唯一确定的是所有给定的数字应该以正确的顺序存在.是否可以构建一个查询?
在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)
但是,您最好为标准化的电话值创建另一列,将其填入触发器并对其进行索引,以便您可以更有效地进行查询.
如果您可以更改表(假设它是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字段,因此在查询时不会产生性能损失 - 值创建并存储在表中,并且可作为普通列使用.
在此,您现在可以很容易地查询.
渣
由于我不知道你在寻找什么 RDBMS,我将给出最通用的方法:
phonenumber like '%5%5%5%1%2%3%4%5%6%'
Run Code Online (Sandbox Code Playgroud)
这假设所有电话号码至少具有相同的长度(以数字为单位)。