我正在使用SQL Server 2012.我需要使用单个文本字段来实现搜索功能。
假设我有下表:
--------------------------------------------------------------------------------
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.
-------------------------------------------------------------------------------
“John Doe”:
-------------------------------------------------------------------------------
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
-------------------------------------------------------------------------------
“for 2010 xelle”:
FIRSTNAME LASTNAME CITY PROMOYEAR EMPLOYOR
--------------------------------------------------------------------------------
Marc Forestier Bruxelle 2010 Private bank
--------------------------------------------------------------------------------
此示例使用单个表;实际上我的5列来自4个不同的表,因此实现全文搜索会有点复杂!
答案 0 :(得分:2)
如何添加其他字段,例如包含来自其他字段的所有信息的文本字段。
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肯定不会起作用,但我希望你能理解我提出的建议。您应该获得一行中搜索单词数量最多的行。但是' IN' SQL中的运算符要求您创建一些动态SQL。
当你写这篇文章时,你已经尝试了几乎所有的东西,我认为SQL不能单独完成。
答案 1 :(得分:2)
这似乎是Sql Full Text Indexing设计的工作。
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;
<德尔>
幸运的话,您可以使用[`CONTAINS`](http://technet.microsoft.com/en-us/library/ms187787.aspx)或`FREETEXT`执行查询,例如:
选择 *
来自mytable
在哪里包含((FirstName,LastName,City,TextPromoYear,Employer),
'为OR 2010 OR xelle')
查询语法并不完全符合您的要求,但您可以根据`CONTAINS`的要求调整所需的“空格分隔”查询。
德尔>
修改强>
这并不像这样容易。通配符*
只能用作后缀,您还需要聚合列以搜索所有列。
完整条款:
SELECT *
FROM mytable
WHERE CONTAINS(*, 'John and Doe');
对于部分搜索,您可能需要使用vanilla LIKE
来测试未知前缀(*xelle)
:
SELECT *
FROM mytable
WHERE CONTAINS(*, '"for*" and 2010') AND SearchableComputedColumn like '%elle%';
答案 2 :(得分:0)
这是一个解决方案。
我将搜索限制为6个字。 对于每个单词,我检查它是否存在于连接列中。 我得到了一个&#34;得分&#34;对于每条记录,每次在其中找到一个单词时添加+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
评论