Пример данных:
$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, поскольку «Люкс 200» является вариацией «Люкс # 200».$phone
будет соответствовать record_id
125, поскольку '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 (поиск в свободном тексте) все это здорово, но я не уверен, как реализовать их, чтобы получить желаемые результаты.Я не против запустить несколько запросов для каждого, например, запрос для $address_1
match и другой для $address_2
match и так далее.Я также знаю, что будут ложные срабатывания, а также ложные отрицания, но я надеюсь, что точность составляет около 75% (или лучше).
Один ВАЖНО примечание - это то, что PostgresНа сервере запущена версия 7.4 , и нет планов по обновлению.
Также для большей сложности запроса существует несколько address_1
, address_2
, zip
и * 1042.* (Вспомните отдельный адрес / телефон для дома и офиса)
Вот мои первые попытки решить эту проблему:
У меня была идея создать наиболее распространенные форматы и затем передать их в качестве параметров в запросе.
Что-то вроде:
$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 (из стекового вопроса # 1) для каждого дополнительного поля поиска ищите, как Office и Home