PHP MySQL查询以查找数据库中最接近的匹配项

时间:2019-05-30 12:11:24

标签: mysql

我有一个经销店的数据库,这些经销店被分配了英国邮政编码的外发要素作为其“补丁”。也就是说,通常为1个或2个字符,因此,例如,安多弗的经销店将负责处理以DT开头的邮政编码的任何查询。但是,有些经销店共享一个补丁,例如,一个经销店可以照顾GU25,而另一个经销店则照顾GU26。

我需要能够使用查询来识别正确的经销商。

到目前为止,我已经设法从查询表单提交中提取邮政编码的外部元素。

现在,我需要搜索数据库。但是,精确匹配将无法正常工作,因为如果补丁被分割,我需要保留完整的向外元素。

示例。

1)客户输入DT1 1XL。我提取了“ DT1”,但需要将其与“ DT”匹配。

2)客户输入GU25 4QF。我提取了“ GU25”,我需要将其与GU25匹配。

$sql = "SELECT * FROM table WHERE outward='DT1'"; 

我希望这本质上是返回,“ 没有完全匹配,但我们确实找到了 DT ”。

或者,如果我们搜索GU25,则“完全匹配!”。

所以我本质上需要找到最接近的匹配项。任何想法将不胜感激。

2 个答案:

答案 0 :(得分:0)

最后,我通过两步查询过程解决了这个问题。

第一步是寻找完整的外部元素的匹配项,如果无法产生我使用的结果

$outward = preg_replace('/[0-9]+/', '', $outward);

删除向外的数字元素,然后再次运行搜索。

如果该技术能够找到最接近的匹配项,那将是很好的选择,但这种解决方案并不会太笨重且行之有效。

答案 1 :(得分:0)

有很多很多方法可以给这只猫剥皮。无论您选择哪种解决方案,都应采用最佳实践,以减少对数据库的访问。我的意思是,一次旅行使两个查询成为一个UNION优于两次单独的旅行。

以下是您可以使用的一个查询:(Demo

模式(MySQL v5.7)

CREATE TABLE `test` (
    `outward` varchar(255)
);

INSERT INTO `test` VALUES
('AB5 8YU'),
('DT1 1XL'),
('DT2 9XL'),
('DT25 1XL'),
('DT11 4XL'),
('GU25 4QF'),
('GU2 3RN');

查询

SELECT outward,
FROM test
WHERE outward LIKE 'DT%'
ORDER BY
    IF(LOCATE('DT1 ', outward), 0, 1),
    CAST(SUBSTRING_INDEX(REPLACE(outward, 'DT', ''), ' ', 1) AS UNSIGNED);

结果集:

| outward  |
| -------- |
| DT1 1XL  |
| DT2 9XL  |
| DT11 4XL |
| DT25 1XL |

结果集始终在完全匹配之前对完全匹配进行排序。遍历结果集行时,可以使用strpos()快速检查是否完全匹配。或者,您可以在结果集中传递“ matchType”标志,以使处理更加容易。 (https://www.db-fiddle.com/f/mWHgBHDTCJ7uyseovygtRe/1

在将这些变量输入查询之前,请确保验证/清除用户输入。并使用带占位符的准备好的语句。

您将需要两个单独的子字符串来进行查询:

  1. 前导字母
  2. 直到并包括第一个遇到的空格的字符。 (请注意LOCATE()调用中包含的空格。)

将来,当您遇到mysql问题时,请在您的问题中提供dbfiddle链接。这样可以弄清楚架构,为志愿者提供一个即时而准确的测试场,这将不可避免地为您提供更好,更快和更正确的答案。