簡體   English   中英

選擇查詢以將多個列與多個關鍵字匹配

[英]select query to match multiple columns with multiple keywords

我需要編寫一個選擇查詢,該查詢將在單個表中搜索從諸如"John Doe Engineering"類的用戶輸入查詢字符串中提取的單詞。 該字符串可以包含一個或多個單詞。 查詢字符串將作為參數傳遞到存儲過程中。 總共需要搜索大約20列。 我的第一個想法是這樣的:

SELECT *
FROM Employees
WHERE FirstName LIKE '%John%' OR FirstName LIKE '%Doe%' OR FirstName LIKE '%Engineering%'
WHERE LastName LIKE '%John%' OR LastName LIKE '%Doe2%' OR LastName LIKE '%Engineering%'
WHERE Manager LIKE '%John%' OR Manager LIKE '%Doe%'OR Manager LIKE '%Engineering%'
WHERE Department LIKE '%John%' OR Department LIKE '%Doe%'OR Department LIKE '%Engineering%'
--repeat for 16 more table columns

但是我不確定如何根據用戶查詢字符串輸入最佳地生成查詢語法。 此外,這似乎是效率非常低的查詢。 在這種情況下,使用full text search會更好嗎? 我想知道最好的方法是什么?

就像其他人所說的那樣-全文搜索可能是此類事情的最佳解決方案。 就是說,我認為提供T-SQL解決方案會很有趣。

快速免責聲明1

*我強烈建議您不要使用以下解決方案-這是一個有趣的小型SQL練習; 性能會很差。 另外-我演示了兩種非常有效的字符串拆分方法:一種是使用Jeff Moden的DelimitedSplit8K,另一種是使用PARSENAME *

快速免責聲明2

我應該指出一些將列連接成單個字符串的問題,這可能會導致誤報。 考慮以下查詢:

DECLARE @search varchar(100) = 'ab';

WITH sampleData AS (SELECT fn, ln FROM (VALUES ('aa', 'bb'), ('cc', 'dd')) t(fn,ln))
SELECT * 
FROM sampleData
WHERE CONCAT(fn,ln) LIKE '%'+@search+'%';

即使“ ab”在任一列中都不存在,上述查詢將返回第一條記錄。 因此,您可以將WHERE(或John的示例中的CHARINDEX)更改為如下形式:

WHERE CONCAT(fn, '|||', ln) LIKE '%'+@search+'%';

我的解決方案

-- SAMPLE DATA 
-------------------------------------------------
DECLARE @employees TABLE 
(
  FirstName  varchar(100),
  LastName   varchar(100),
  Manager    varchar(100),
  Department varchar(100)
);

INSERT @employees
SELECT * 
FROM 
(
  VALUES 
    ('bob', '****', 'ddd', 'sss'),
    ('fff', 'fred', 'obx', 'ccc'),
    ('Sue', 'abcd', 'ddd', 'zzz'),
    ('ddd', 'dcba', '123', 'fobbb')
) xx(x1, x2, x3, x4);

-- Solution #1: when @search has <= 4 "items"
-------------------------------------------------
DECLARE @search varchar(100) = 'xx bb ff zz';

SELECT e.*
  --,PARSENAME(REPLACE(@search,' ','.'), N) AS matchedPattern
FROM (VALUES (1),(2),(3),(4)) t(n)
CROSS JOIN @employees e
WHERE 
  CHARINDEX
  (
    PARSENAME(REPLACE(@search,' ','.'), N), 
    CONCAT(FirstName, '|||', LastName, '|||', Manager, '|||', Department)
  ) > 0;

-- Solution #2: when @search has (or can have) > 4 "items"
-------------------------------------------------

-- for this you will need delimitedsplit8k: http://www.sqlservercentral.com/articles/Tally+Table/72993/
SELECT e.*
FROM dbo.delimitedsplit8k(@search, ' ')
CROSS JOIN @employees e
WHERE 
  CHARINDEX
  (
    item, 
    CONCAT(FirstName, '|||', LastName, '|||', Manager, '|||', Department)
  ) > 0;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM