在INNER JOIN的一部分中使用LIKE子句

时间:2020-03-05 18:41:39  来源:igfitidea点击:

可以/应该在构建存储过程/查询时将LIKE准则用作INNER JOIN的一部分吗?我不确定我在问正确的事情,所以让我解释一下。

我正在创建一个过程,该过程将在包含文本的列中采用要搜索的关键字列表。如果我坐在控制台上,可以这样执行:

SELECT Id, Name, Description
  FROM dbo.Card
 WHERE Description LIKE '%warrior%' 
       OR
       Description LIKE '%fiend%' 
       OR 
       Description LIKE '%damage%'

但是我花一点时间在存储过程中进行"强类型"列表解析的一个技巧是将列表解析为表变量/临时表,将其转换为正确的类型,然后对该表进行INNER JOIN在我的最终结果集中。向过程发送例如整数ID的列表时,这非常有用。我最终有一个看起来像这样的最终查询:

SELECT Id, Name, Description
  FROM dbo.Card
       INNER JOIN @tblExclusiveCard ON dbo.Card.Id = @tblExclusiveCard.CardId

我想将此技巧与字符串列表一起使用。但是,由于我要查找特定的关键字,因此我将使用LIKE子句。因此,理想情况下,我想我的最终查询应如下所示:

SELECT Id, Name, Description
  FROM dbo.Card
       INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' + @tblKeyword.Value + '%'

这可能/建议吗?

有没有更好的方法来做这样的事情?

我将通配符放在条款的两端的原因是,在卡文本中使用了" archfiend"," beast-warrior"," direct-damage"和" battle-damage"这两个术语。

我得到的印象是,根据性能,我可以使用我指定的查询,也可以使用全文本关键字搜索来完成相同的任务?

除了让服务器在我要进行文本搜索的字段上进行文本索引之外,还有什么需要做的吗?

解决方案

回答

似乎我们正在寻找全文搜索。因为我们要针对卡片说明查询一组关键字并找到匹配项?正确的?

回答

就个人而言,我以前做过,对我来说效果很好。我能看到的唯一问题可能是未索引列的问题,但是我认为我们在where子句中也会遇到同样的问题。

我对建议只是看一下两者之间的执行计划。我敢肯定,视情况而定,哪一个更好,就像所有好的编程问题一样。

回答

性能将取决于所使用的实际服务器,数据的架构以及数据量。使用MS SQL Server的当前版本,该查询应该可以正常运行(MS SQL Server 7.0的语法存在问题,但已在SP2中解决)。

我们是否通过探查器运行该代码?如果性能足够快并且数据具有适当的索引,则应该一切就绪。

回答

第一个查询将起作用,但需要全表扫描,因为该列上的任何索引都将被忽略。我们还必须执行一些动态SQL才能生成所有LIKE子句。

如果我们使用的是SQL Server,请尝试全文搜索,或者查看Lucene的实现之一。乔尔(Joel)最近谈到了他的成功。

回答

像'%fiend%'绝不会使用寻道,而像'fiend%'会那样。只是通配符搜索是不可靠的

回答

@ Dillie-O
这个桌子多大?
Description字段的数据类型是什么?

如果两者都不大,那么全文搜索将是多余的。

@ Dillie-O
也许不是我们要找的答案,但我会提倡架构更改...

建议的架构:

create table name(
    nameID identity / int
   ,name varchar(50))

create table description(
    descID identity / int
   ,desc varchar(50)) --something reasonable and to make the most of it alwase lower case your values

create table nameDescJunc(
    nameID  int
    ,descID int)

这将使我们可以使用索引,而无需在解决方案上实施任何操作,并使数据保持原子性。

相关:推荐的用于标记或者标记的SQL数据库设计

回答

a trick I picked up a little while go
  to do "strongly typed" list parsing in
  a stored procedure is to parse the
  list into a table variable/temporary
  table

我认为我们在这里可能暗示的是将要包含的关键字放入表中,然后使用关系除法查找匹配项(也可以使用另一个表来排除单词)。有关SQL中的有效示例,请参见Joe Celko的"关键字搜索"。

回答

试试这个;

SELECT Id, Name, Description
FROM dbo.Card
INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' + 
                                CONCAT(CONCAT('%',@tblKeyword.Value),'%') + '%'