【发布时间】:2011-01-21 17:55:55
【问题描述】:
示例数据:
$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'
这可以是单独的查询,但我需要在地址中搜索部分匹配项,并在手机中搜索 zip 和完整匹配项。
所以
$address_1 将部分匹配 record_id 123 作为 '123 Main St.'是“123 main street”的变体$address_2 将匹配 record_id 124,因为“Suite 200”是“Suite #200”的变体$phone 将匹配 record_id125 作为 '1235551212 ' 是 '1-123-555-1212' 的变体$zip 将匹配 record_id 123 和 124,因为 '12345' 是 '12345-1111' 的变体并且匹配到 '12345'
注意:
也可以切换值,这意味着$address_1 可以这样格式化:'123 main street' 和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(请考虑单独的地址/电话,例如家庭和办公室)
这是我第一次尝试解决这个问题:
我有一个想法来生成最常见的格式,然后将它们作为参数传递给查询。
类似:
$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%'
)
似乎我必须做出很多变化,但我仍然不确定这是否是最佳方式。
更新:
这有点工作(来自堆栈问题 #2)
SELECT *
FROM tbl_name
WHERE LOWER(address_1) ILIKE LOWER('123 Main%')
使用 UNION 方法(来自 Stack Question #1)对每个添加地址字段搜索,如 Office 和 Home
【问题讨论】:
标签: sql postgresql query-optimization