【发布时间】:2016-10-21 17:29:03
【问题描述】:
我有一个查询,该查询当前采用单个用户提供的搜索字符串,并尝试搜索一个表,该表包含一个单独的 firstName 和 lastName 列。如果搜索字符串中有空格,那么它运行的查询本质上是这样的:
SELECT * FROM table
WHERE table.firstName LIKE @firstName + '%'
AND table.lastName LIKE @lastName + '%'
我们不需要关心搜索字符串中没有空格的情况。
一般情况很简单 - 将搜索字符串用空格分隔,第一部分是名字,第二部分是姓氏。所以,“鲍勃·史密斯”变成了
@firstName = "Bob", @lastName = "Smith"
我关心的是如何处理名称超过两个单词的情况。像
这样的情况table.firstName table.lastName
--------------- --------------
Bob van Smith
Billy Bob Smith
Bob van der Smith
Billy Bob van der Smith
等等。现在我们在第一个空格上进行拆分,所以第一个示例“Bob van Smith”将起作用,因为它会分解为
@firstName: "Bob", @lastName: "van Smith"
但是,这并没有捕捉到第二种情况“Billy Bob Smith”,因为它分裂成
@firstName: "Billy", @lastName: "Bob Smith"
当前设置也适用于第三个测试用例,因为它分为
@firstName: "Bob", @lastName: "van der Smith"
如果有办法让它发挥作用,最后一种情况将是加分。
我的第一个想法是将查询修改为
SELECT * FROM table
WHERE table.firstName + ' ' + table.lastName LIKE '%' + @searchString + '%'
但这被否决了,因为我们不希望有人只搜索字母“a”,例如返回大量记录,而双通配符会创建这些记录。
进行这种字符串拆分/搜索有什么技巧吗?这不可能是第一次出现问题,但是在互联网上搜索除了“空间分割,但请注意,如果名称中有 3 个或更多单词,它将不起作用。”
我觉得类似于将“名称之间”作为@firstName 和@lastName 的一部分并做一些聪明的事情,或者使SQL 部分更通用,然后在我的C# 代码中使用LINQ 进行额外的过滤,但我想找到一个解决方案。
【问题讨论】:
-
这是一个重要的问题。例如,像 Maria de los Angeles Gomez de la Cruz 这样的名字。我认为你的设计把你放在了一个无法轻易逃脱的盒子里。一个强大的名称匹配算法必须考虑到人们以不同方式对待相同名称的可能性,并允许名称单词丢失、跨越第一个/最后一个边界、拼写错误等。这对于一个简单的 SO 答案来说太宽泛了。
-
@hatchet 是的,这就是我害怕的。我继承了这个设计,并且拒绝对其进行根本性的改变,所以我认为看看是否有我遗漏的技巧不会有什么坏处