[英]SQL simple search functionality across multiple tables
我正在使用SQL Server2012。我需要使用單個文本字段實現搜索功能。
假設我有下表:
--------------------------------------------------------------------------------
FIRSTNAME LASTNAME CITY PROMOYEAR EMPLOYOR
--------------------------------------------------------------------------------
John Doe Boston 2005 Mc Donald
Marc Forestier Bruxelle 2010 Private bank
Céline Durand Paris 1999 Food SA
Simon Forestier Toulouse 2001 Forestier SARL
John Smith New York 1992 Events Org.
Sonia Grappe Toulon 2010 Forestier SARL
--------------------------------------------------------------------------------
行為如下:
LIKE
我嘗試了很多事情,但這並不像看起來那么簡單。
一些例子:
“約翰”:
-------------------------------------------------------------------------------
FIRSTNAME LASTNAME CITY PROMOYEAR EMPLOYOR
-------------------------------------------------------------------------------
John Doe Boston 2005 Mc Donald
John Smith New York 1992 Events Org.
-------------------------------------------------------------------------------
“約翰·多伊”:
-------------------------------------------------------------------------------
FIRSTNAME LASTNAME CITY PROMOYEAR EMPLOYOR
-------------------------------------------------------------------------------
John Doe Boston 2005 Mc Donald
-------------------------------------------------------------------------------
“弗賴斯”:
-------------------------------------------------------------------------------
FIRSTNAME LASTNAME CITY PROMOYEAR EMPLOYOR
-------------------------------------------------------------------------------
Marc Forestier Bruxelle 2010 Private bank
Simon Forestier Toulouse 2001 Forestier SARL
Sonia Grappe Toulon 2010 Forestier SARL
-------------------------------------------------------------------------------
“ 2010年xelle”:
FIRSTNAME LASTNAME CITY PROMOYEAR EMPLOYOR
--------------------------------------------------------------------------------
Marc Forestier Bruxelle 2010 Private bank
--------------------------------------------------------------------------------
這個例子使用一個表。 實際上,我的5列來自4個不同的表,因此實現全文搜索要稍微復雜一點!
如何添加另一個字段,例如包含其他字段中所有信息的文本字段。
FIRSTNAME LASTNAME CITY PROMOYEAR EMPLOYOR SEARCHFIELD
John Doe Boston 2005 Mc Donald John Doe Boston 2005 Mc Donald
並在此字段上進行搜索。 它不是很優雅,但是可以工作。
在下面添加:
我認為SQL語法不能滿足您的所有需求,但您可以采取其他解決方法。 創建一個包含所有要搜索的單詞的表:
create table searchtable
(
rowid int, --key to the id for the row in your table
mothertableName varchar(), -- name of the table if necessary
motherfieldName varchar(), -- name of field
word varchar() -- the actual word to be searchable
)
搜索單詞及其出現次數最多的地方:
SELECT * FROM myTable WHERE id IN(
SELECT rid as id, MAX(c) FROM (
SELECT rowid as rid, COUNT(rowid) as c FROM Searchtable WHERE word IN ('john','doe')
)
)
上面的SQL肯定不會起作用,但是希望您對我的建議有所了解。 您應該獲得最多搜索詞的一行。 但是SQL中的“ IN”運算符要求您動態創建一些SQL。
當您寫到您已經嘗試了幾乎所有內容時,我認為SQL不能獨自完成。
這似乎是Sql全文索引設計的工作。
AFAIK全文索引不適用於數字類型,因此您可能需要為任何日期或數字類型添加計算列,例如,如果PromoYear
為數字:
ALTER TABLE MyTable
ADD TextPromoYear AS CAST(PromoYear AS NVARCHAR(4))
PERSISTED;
您需要在數據庫中設置全文目錄:
CREATE FULLTEXT CATALOG CAT_MyCat AS DEFAULT;
假設您有一個名為PK_MyTable
的主鍵,請創建全文索引:
CREATE FULLTEXT INDEX ON MyTable(FirstName, LastName, City, TextPromoYear,
Employer)
KEY INDEX PK_MyTable;
編輯
這不是那么容易。 通配符*
只能用作后綴,並且您還需要匯總列以在所有列中進行搜索。
完整條款:
SELECT *
FROM mytable
WHERE CONTAINS(*, 'John and Doe');
對於部分搜索,您可能需要求助於使用香草的LIKE
來測試未知前綴(*xelle)
:
SELECT *
FROM mytable
WHERE CONTAINS(*, '"for*" and 2010') AND SearchableComputedColumn like '%elle%';
這是一個解決方案。
我已將搜索范圍限制為6個字。 對於每個單詞,我檢查它是否存在於串聯的列中。 每當在其中找到一個單詞時,我都會在+1上加上一個“分數”。 我返回得分最高的記錄。
功能 :
CREATE FUNCTION [dbo].[SEARCH_SINGLE] (
@langId INT = 4,
@searchString VARCHAR(MAX) = NULL
)
RETURNS TABLE
AS
RETURN
WITH words AS (
SELECT Name as Val, ROW_NUMBER() OVER(ORDER BY Name) as Num FROM [dbo].splitstring(@searchString, ' ')
),
results AS (
SELECT DISTINCT
...
CASE WHEN EXISTS(SELECT 1 FROM words WHERE Num = 1 AND (ISNULL(a.[FIRSTNAME], '') + ' ' + ISNULL(a.[LASTNAME], '') + ' ' + ISNULL(c.[CITY], '') + ' ' + ISNULL(j.[PROMO_YEAR], '') + ' ' + ISNULL(e.[EMPLOYOR], '')) like '%'+Val+'%') THEN 1 ELSE 0 END +
CASE WHEN EXISTS(SELECT 1 FROM words WHERE Num = 2 AND (ISNULL(a.[FIRSTNAME], '') + ' ' + ISNULL(a.[LASTNAME], '') + ' ' + ISNULL(c.[CITY], '') + ' ' + ISNULL(j.[PROMO_YEAR], '') + ' ' + ISNULL(e.[EMPLOYOR], '')) like '%'+Val+'%') THEN 1 ELSE 0 END +
CASE WHEN EXISTS(SELECT 1 FROM words WHERE Num = 3 AND (ISNULL(a.[FIRSTNAME], '') + ' ' + ISNULL(a.[LASTNAME], '') + ' ' + ISNULL(c.[CITY], '') + ' ' + ISNULL(j.[PROMO_YEAR], '') + ' ' + ISNULL(e.[EMPLOYOR], '')) like '%'+Val+'%') THEN 1 ELSE 0 END +
CASE WHEN EXISTS(SELECT 1 FROM words WHERE Num = 4 AND (ISNULL(a.[FIRSTNAME], '') + ' ' + ISNULL(a.[LASTNAME], '') + ' ' + ISNULL(c.[CITY], '') + ' ' + ISNULL(j.[PROMO_YEAR], '') + ' ' + ISNULL(e.[EMPLOYOR], '')) like '%'+Val+'%') THEN 1 ELSE 0 END +
CASE WHEN EXISTS(SELECT 1 FROM words WHERE Num = 5 AND (ISNULL(a.[FIRSTNAME], '') + ' ' + ISNULL(a.[LASTNAME], '') + ' ' + ISNULL(c.[CITY], '') + ' ' + ISNULL(j.[PROMO_YEAR], '') + ' ' + ISNULL(e.[EMPLOYOR], '')) like '%'+Val+'%') THEN 1 ELSE 0 END +
CASE WHEN EXISTS(SELECT 1 FROM words WHERE Num = 6 AND (ISNULL(a.[FIRSTNAME], '') + ' ' + ISNULL(a.[LASTNAME], '') + ' ' + ISNULL(c.[CITY], '') + ' ' + ISNULL(j.[PROMO_YEAR], '') + ' ' + ISNULL(e.[EMPLOYOR], '')) like '%'+Val+'%') THEN 1 ELSE 0 END as Nb
FROM
...
WHERE
...
)
SELECT
...
FROM
results
WHERE
Nb = (SELECT MAX(Nb) FROM results)
AND Nb <> 0
評論?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.