关于sql:在INNER JOIN的一部分中使用LIKE子句

关于sql:在INNER JOIN的一部分中使用LIKE子句

Use a LIKE clause in part of an INNER JOIN

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

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

1
2
3
4
5
6
7
SELECT Id, Name, Description
  FROM dbo.Card
 WHERE Description LIKE '%warrior%'
       OR
       Description LIKE '%fiend%'
       OR
       Description LIKE '%damage%'

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

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

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

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

这可能/建议吗?

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

之所以在该条款的两端加上通配符,是因为在卡文本中使用了" archfiend"," beast-warrior"," direct-damage"和" battle-damage"这两个术语。

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

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


试试这个

1
2
    SELECT * FROM Table_1 a
    LEFT JOIN Table_2 b ON b.type LIKE '%' + a.type + '%'

这种做法并不理想。请谨慎使用。


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

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


尝试...

1
SELECT * FROM table11 a INNER JOIN  table2 b ON b.id LIKE (SELECT '%'+a.id+'%') WHERE a.city='abc'.

对我有用。:-)


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的"关键字搜索"。


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

如果其中一个很小,则全文搜索将显得过大。

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

建议的架构:

1
2
3
4
5
6
7
8
9
10
11
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数据库设计


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

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


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


尝试一下;

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

LIKE \\'%fiend%\\'永远不会使用查找,LIKE \\'fiend%\\'会使用寻道。仅仅是通配符搜索是不可靠的


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

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


推荐阅读