[英]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.