示例数据:
$address_1 = '123 Main St.';
$address_2 = 'Suite 200';
$phone = '1235551212';
$zip = '12345';
示例数据库:
record_id, address_1, address_2, zip, phone
123, '123 main street', '', '12345', '1234567890'
124, '500 E. Ninja Road', 'Suite #200', '12345-1111', '(321)654-0987'
125, '222 where 4 east circle', 'P.O. Box 3', '11111', '1-123-555-1212'
这可以是单独的查询,但我需要在地址和邮编中搜索部分匹配以及手机中的完整匹配。
所以
$address_1
会将record_id
123部分匹配为'123 Main St.'是'123主要街道'的变种
$address_2
匹配record_id
124,因为'Suite 200'是'Suite#200'的变体
$phone
匹配record_id
125,因为'1235551212'是'1-123-555-1212'的变体
$zip
符合record_id
123& 124为'12345'是'12345-1111'的变体,与'12345'的匹配
注意:
也可以切换值,这意味着$address_1
可以这样形成:'123主要街道'和record_id
123可以是这样的:'123 Main St.' (这适用于所有领域)
我被建议尝试ILIKE, LIKE, SIMILAR,CITEXT和FTS (Free Text Search)所有这些都很棒,但我不确定如何实施它们以获得我想要的结果。
我不介意为每个查询运行多个查询,例如$address_1
匹配的查询和$address_2
匹配的另一个查询,依此类推。我也知道会有误报和误报,但我希望能够达到75%(或更高)的准确性。
一个重要注意,Postgres服务器正在运行版本7.4 ,并且没有升级计划。
此外,为了向查询添加更多复杂性,还有多个address_1
,address_2
,zip
和phone
(想想家庭和办公室的单独地址/电话)< / p>
以下是我首次尝试解决此问题:
我有想法制作最常见的格式,然后将它们作为查询中的参数传递。
类似的东西:
$address_1 = array(
'123 Main St.', // original
'123 main st.', // lower case
'123 Main St.', // First Letter Upper Case
'123 MAIN ST.', // ALL Upper Case
'123 Main St', // remove punctuation original
'123 main st', // remove punctuation lower case
'123 Main St', // remove punctuation First Letter Upper Case
'123 MAIN ST', // remove punctuation ALL Upper Case
'123 Main', // remove last word original
'123 main', // remove last word lower case
'123 Main', // remove last word First Letter Upper Case
'123 MAIN', // remove last word ALL Upper Case
'123 Main%', // remove last word original with wildcard
'123 main%', // remove last word lower case with wildcard
'123 Main%', // remove last word First Letter Upper Case with wildcard
'123 MAIN%' // remove last word ALL Upper Case with wildcard
);
然后查询将是这样的:
SELECT *
FROM tbl_name
WHERE address_1 IN (
'123 Main St.', '123 main st.', '123 Main St.',
'123 MAIN ST.', '123 Main St', '123 main st',
'123 Main St', '123 MAIN ST', '123 Main',
'123 main', '123 Main' '123 MAIN',
'123 Main%', '123 main%', '123 Main%',
'123 MAIN%'
)
看起来好像我要做的很多变化,我仍然不确定这是否是最佳方式。
更新:
这种方法有用(来自Stack Question#2)
SELECT *
FROM tbl_name
WHERE LOWER(address_1) ILIKE LOWER('123 Main%')
使用UNION方法(来自Stack Question#1)为Office和Home等每个附加地址字段搜索
答案 0 :(得分:2)
如果我理解正确,你需要从场到场的零碎比赛(例如'123'匹配'123-111'和'12345'而不是'122234'或'122-345')你需要避免所有匹配时的符号。这是正确的吗?
下面的伪代码是我首先尝试的:
听起来最好的方法是通过ILIKE查询,其中百分号是片段的开头和结尾,例如:
SELECT * FROM [TABLE_NAME] WHERE address_1 ILIKE '%fragment%'
您必须多次执行此查询,这可能会让您感到头痛,但我相信这可能会让您满意。
答案 1 :(得分:1)
我对方法有一些建议。
我强烈建议从电话号码中删除所有非数字。 你可以用postgres做这个
SELECT id FROM [table] WHERE regexp_replace(phone, '[^0-9]', '', 'g') = [$phone];
我不确定这是否适合您,但许多地址验证系统会忽略除匹配之外的所有数据。
例如,
12-34 E. 5th street
APT 6B
City, ST 78910
将匹配12345678910.您可以使用类似的内容实现...
select * FROM [table]
WHERE regexp_replace(address_1 || address_2 || zip, '[^0-9]', '', 'g') = $addressNumbers;
另外你可以调查postgres SoundEx扩展。 http://www.postgresql.org/docs/8.3/static/fuzzystrmatch.html这可能有助于简化纠正拼写变化,套管,间距,标点符号等。