Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
跨多个表的SQL简单搜索功能_Sql_Sql Server_Search - Fatal编程技术网

跨多个表的SQL简单搜索功能

跨多个表的SQL简单搜索功能,sql,sql-server,search,Sql,Sql Server,Search,我正在使用SQL Server 2012。我需要使用单个文本字段实现搜索功能 假设我有下表: -------------------------------------------------------------------------------- FIRSTNAME LASTNAME CITY PROMOYEAR EMPLOYOR -------------------------------------------------------------

我正在使用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  
--------------------------------------------------------------------------------
行为如下:

  • 必须在整个列中搜索所有单词(空格分隔)
  • 每个单词都应使用类似于的
  • 如果只搜索一个单词,则返回包含该单词的所有记录
  • 如果搜索了多个单词,则只返回包含最大数量的不同的单词的记录(参见下面的“forestier”示例)
  • 我需要一个查询,没有TSQL
我尝试了很多东西,但并不像看上去那么简单

一些例子:

“约翰”:

“约翰·多伊”:

“森林人”:

“2010年Xele”:


本例使用单个表;实际上,我的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不能单独做到这一点。

如何添加另一个字段,例如一个包含其他字段所有信息的文本字段

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无法单独完成这项工作。

这似乎是为您设计的工作

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)或“自由文本”,例如: 挑选* 从mytable 其中包含((名字、姓氏、城市、年份、雇主), ‘2010年或2010年或Xele’) 查询语法并不完全是您想要的,但是您可以根据“CONTAINS”的要求将您想要的“空格分隔”查询调整为“and”。 编辑

这可不像这样容易。通配符
*
只能用作后缀,您还需要聚合列以跨所有列进行搜索

完整条款:

SELECT *
FROM mytable
WHERE CONTAINS(*, 'John and Doe');
对于部分搜索,您可能需要使用普通的
进行混合,以测试未知前缀
(*xelle)

这似乎就是我们设计的工作

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)或“自由文本”,例如: 挑选* 从mytable 其中包含((名字、姓氏、城市、年份、雇主), ‘2010年或2010年或Xele’) 查询语法并不完全是您想要的,但是您可以根据“CONTAINS”的要求将您想要的“空格分隔”查询调整为“and”。 编辑

这可不像这样容易。通配符
*
只能用作后缀,您还需要聚合列以跨所有列进行搜索

完整条款:

SELECT *
FROM mytable
WHERE CONTAINS(*, 'John and Doe');
对于部分搜索,您可能需要使用普通的
进行混合,以测试未知前缀
(*xelle)

这里有一个解决方案

我已将搜索限制为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
创建函数[dbo].[SEARCH\u SINGLE](
@langId INT=4,
@searchString VARCHAR(MAX)=NULL
)
返回表
作为
返回
以文字为中心(
选择名称作为Val,将(按名称排序)上的行_NUMBER()作为[dbo]中的Num。拆分字符串(@searchString,'))
),
结果为(
选择不同的
...
存在时的大小写(从Num=1的单词中选择1和(ISNULL(a.[FIRSTNAME],'')+''+ISNULL(a.[LASTNAME],'')+''+ISNULL(c.[CITY],'')+''+ISNULL(j.[PROMO_YEAR],'')+''+ISNULL(e.[EMPLOYOR],'')类似'''''+Val+'%'))然后选择1,其他0结束+
存在时的大小写(从Num=2的单词中选择1,并且(ISNULL(a.[FIRSTNAME],'')+''+为