部分/缩写名称匹配

时间:2018-10-11 14:02:55

标签: mysql fuzzy-search

我正在尝试编写将部分匹配项与存储的名称值匹配的查询。

我的数据库如下

  

Blockquote

FirstName | Middle Name | Surname
----------------------------------
Joe       | James       | Bloggs
J         | J           | Bloggs
Joe       |             | Bloggs
Jane      |             | Bloggs

现在,如果用户输入的姓名为

J Bloggs

我的查询应该返回所有4行,因为它们都是潜在的匹配项。

类似地,如果用户输入名称

J J Bloggs

应该返回所有行。

如果用户输入的姓名为

Joe Bloggs

仅应返回前三个。

我尝试了以下

SELECT * 
FROM PERSON 
WHERE CONCAT(' ',FirstName,' ',MiddleName,' ', Surname) LIKE '% Joe%'
    AND CONCAT(' ',FirstName,' ',MiddleName,' ', Surname, ' ') LIKE '% Bloggs%';

但这不会返回'J J Bloggs'。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

如果我正确理解了您的逻辑,则三个输入名称组成部分中的任何一个(如果是表中值的子字符串)都被视为匹配项,反之亦然。也就是说,J匹配Joe,但是Joe也匹配J。使用此逻辑,我们可以编写以下查询:

SELECT *
FROM yourTable
WHERE
    (INSTR(FirstName, 'J') > 0 OR INSTR('J', FirstName) > 0) AND
    (INSTR(MiddleName, 'J') > 0 OR INSTR('J', MiddleName) > 0 OR MiddleName IS NULL) AND
    (INSTR(Surname, 'Bloggs') > 0 OR INSTR('Bloggs', Surname) > 0);

Demo

请注意,中间名还有一些其他逻辑。如果记录中缺少中间名(即NULL),那么我们就会提出要求匹配中间名的要求。

答案 1 :(得分:0)

我认为您可能需要OR而不是AND ...

SELECT * 
FROM PERSON 
WHERE CONCAT(' ',FirstName,' ',MiddleName,' ', Surname) LIKE '% Joe%'
    OR CONCAT(' ',FirstName,' ',MiddleName,' ', Surname, ' ') LIKE '% Bloggs%';