【问题标题】:Use a LIKE clause in part of an INNER JOIN在 INNER JOIN 的一部分中使用 LIKE 子句
【发布时间】:2010-09-06 10:27:56
【问题描述】:

在构建存储过程/查询时,我可以/应该使用 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”术语。

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

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

【问题讨论】:

    标签: sql sql-server design-patterns


    【解决方案1】:

    试试这个

        select * from Table_1 a
        left join Table_2 b on b.type LIKE '%' + a.type + '%'
    

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

    【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      试试看……

      select * from table11 a inner join  table2 b on b.id like (select '%'+a.id+'%') where a.city='abc'.
      

      它对我有用。:-)

      【讨论】:

        【解决方案4】:

        您似乎正在寻找全文搜索。因为您想根据卡片描述查询一组关键字并找到任何匹配项?对吗?

        【讨论】:

          【解决方案5】:

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

          我给你的建议是看看两者之间的执行计划。就像所有好的编程问题一样,我相信它会根据情况而有所不同。

          【讨论】:

            【解决方案6】:

            @Dillie-O
            这张桌子有多大?
            描述字段的数据类型是什么?

            如果其中任何一个都很小,那么全文搜索将是多余的。

            @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)
            

            这将使您无需实施固定解决方案即可使用索引,并保持数据原子性。

            相关:Recommended SQL database design for tags or tagging

            【讨论】:

              【解决方案7】:

              我在不久前学到的一个技巧 做“强类型”列表解析 一个存储过程就是解析 列表到表变量/临时 表

              我认为您可能在这里暗示的是将要包含的关键字放入表中,然后使用relational division 查找匹配项(也可以使用另一个表来排除要排除的单词)。有关 SQL 中的工作示例,请参阅Keyword Searches by Joe Celko

              【讨论】:

                【解决方案8】:

                性能取决于您使用的实际服务器、数据架构和数据量。对于当前版本的 MS SQL Server,该查询应该可以正常运行(MS SQL Server 7.0 的语法存在问题,但 it was addressed in SP2)。

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

                【讨论】:

                  【解决方案9】:

                  LIKE '%fiend%' 永远不会使用搜索,LIKE 'fiend%' 会。简单的通配符搜索是不可搜索的

                  【讨论】:

                    【解决方案10】:

                    试试这个;

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

                    【讨论】:

                      猜你喜欢
                      • 2013-05-11
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-05-28
                      • 2012-06-01
                      • 1970-01-01
                      • 2013-08-11
                      相关资源
                      最近更新 更多