Warm tip: This article is reproduced from serverfault.com, please click

sql-在MSSQL中使用多个搜索字符串对多个字段进行过滤

(sql - Filtering on multiple fields using multiple search strings in MSSQL)

发布于 2020-11-30 09:53:47

我想知道如何(以及是否)可以使用多个搜索字符串以有效的方式对多个字段进行过滤。通过订购,你可以确保最重要的命中在顶部。

如果我的用户输入“ mexico maria futter”,则我希望所有行都包含三个搜索项的行。例如(“ John Smith”,“ Donner futter ”,“ Maria Mexico bay”,“ Berlin”)会很受欢迎,但是(“ John Smith”,“ Donnerfulter”,“ Maria Mexico bay”,“ Berlin”)不会很受欢迎

编辑:如果我得到多个匹配,我希望能够按匹配的字段排序,例如,如果我将CustomerName指定为最重要的字段:

(“ Annie Futter的儿子”,“ Maria的公司”,“地址字段”,“墨西哥”)

(“约翰·史密斯”,“唐纳·弗特”,“玛丽亚· 墨西哥湾”,“柏林”)

安妮·弗特森(Annie Futterson)排名第一的原因是“客户名”中存在匹配项。

SELECT * FROM Customers where (CustomerName LIKE '%futter%' OR ContactName LIKE '%futter%' or Address LIKE '%futter%' or City LIKE '%futter%')
AND (CustomerName LIKE '%mexico%' OR ContactName LIKE '%mexico%' or Address LIKE '%mexico%' or City LIKE '%mexico%')
AND (CustomerName LIKE '%maria%' OR ContactName LIKE '%maria%' or Address LIKE '%bianco%' or City LIKE '%maria%');

该查询将需要在Microsoft SQL Server 2012及更高版本上运行。

即使实现我的问题是重复的,对实现此功能的任何帮助也将受到高度赞赏:)

编辑:我编辑查询以产生一个有效的查询,并添加了更多信息。我不知道如何根据优先级对字段进行排名,具体取决于哪个字段受到了影响。

在多列和谓词上包含CONTAINS的全文本搜索-AND不能解决我的问题,因为它不会按命中列进行排名。它也没有解决不同的选择以及这些选择的有效性。

Questioner
remote
Viewed
0
988 2020-12-05 20:56:48

嗯。一种方法是按单词和列汇总匹配项,然后使用该信息进行过滤和排序:

SELECT c.*
FROM Customers c CROSS APPLY
     (SELECT COUNT(DISTINCT word) as num_matched_words,
             SUM(CASE WHEN ColName = 'CustomerName' THEN 1 ELSE 0 END) as customername_matches,
             SUM(CASE WHEN ColName = 'ContactName' THEN 1 ELSE 0 END) as contactname_matches,
             SUM(CASE WHEN ColName = 'Address' THEN 1 ELSE 0 END) as addressname_matches
      FROM (VALUES ('CustomerName', @1, CASE WHEN CustomerName LIKE @1 THEN 1 ELSE 0 END),
                   ('CustomerName', @2, CASE WHEN CustomerName LIKE @2 THEN 1 ELSE 0 END),
                   ('CustomerName', @3, CASE WHEN CustomerName LIKE @3 THEN 1 ELSE 0 END),
                   ('ContactName', @1, CASE WHEN ContactName LIKE @1 THEN 1 ELSE 0 END),
                   ('ContactName', @2, CASE WHEN ContactName LIKE @2 THEN 1 ELSE 0 END),
                   ('ContactName', @3, CASE WHEN ContactName LIKE @3 THEN 1 ELSE 0 END),
                   ('Address', @1, CASE WHEN Address LIKE @1 THEN 1 ELSE 0 END),
                   ('Address', @2, CASE WHEN Address LIKE @2 THEN 1 ELSE 0 END),
                   ('Address', @3, CASE WHEN Address LIKE @3 THEN 1 ELSE 0 END)
           ) v(ColName, Word, IsMatch)
      WHERE IsMatch
     ) v
WHERE num_matched_words = 3
ORDER BY customername_matches DESC,
         contactname_matches DESC,
         addressname_matches DESC;