【问题标题】:Query with LIKE statement for any of the words, not whole使用 LIKE 语句查询任何单词,而不是整个单词
【发布时间】:2014-09-17 12:05:48
【问题描述】:
SELECT *
FROM Products
WHERE Name LIKE '%' +
    (SELECT TOP 1 Gift.Name FROM Gift WHERE Id = 65)
     + '%'

子查询返回诸如“玩具枪”之类的东西。其中一些甚至由三个或更多单词组成。显然,主查询查找包含“玩具枪”的名称。 我想要做的是返回“玩具”或“枪”的所有结果。

有什么建议吗?

【问题讨论】:

  • 您能够并愿意使用全文索引吗?
  • 你可以使用存储过程和/或函数吗?另外,您可以使用其他语言(例如 C#、JAVA)编写自己的应用程序吗?

标签: sql sql-server tsql sql-like


【解决方案1】:
SELECT *
FROM Products
WHERE Name LIKE '%' +
    (SELECT TOP 1 Gift.Name FROM Gift WHERE Id = 65)
     + '%'

我不确定这是否是您想要的,但如果您不想创建函数。

SELECT *
FROM Products
WHERE ' ' + (SELECT TOP 1 Gift.Name FROM Gift WHERE Id = 65) + ' '
  LIKE '%' + ' ' + REPLACE(REPLACE(REPLACE(
       Name,'[','[[]'), '_', '[_]'), '%', '[%]') + ' ' + '%'

.

Gift.Name         Products.Name
' toy gun ' LIKE '% toy %' true
' toy gun ' LIKE '% gun %' true
' toy gun ' LIKE '% toy gun %' true
' toy gun ' LIKE '% guns %' false
' toy gun ' LIKE '% gu %' false
' toy gun ' LIKE '% to %' false
' toy gun ' LIKE '% toys %' false
' toy gun ' LIKE '% gun toy %' false

【讨论】:

    【解决方案2】:
    declare @query varchar(8000)
    select @query='
    SELECT *
    FROM Products
    WHERE Name LIKE ''%' +
        replace((SELECT TOP 1 Gift.name FROM Gift),' ','%'' or name like ''%')
         + '%'''
    
        exec (@query)
    

    【讨论】:

    • 嘿,好主意,但它不起作用。 'Toy Gun' 将变成 'Toy%Gun',但仍然不会针对 'Toy' 返回 true。您所做的只是不必完全匹配“Toy Gun”,而是可以匹配“Toy”加上任何字符集加上“Gun”。但是“枪”仍然必须在那里。
    • 它对我有用。非常感谢...实现它真的很棘手。
    【解决方案3】:

    您将需要创建拆分列文本的函数。这是一种可能的方法:

    http://www.sqlservercentral.com/blogs/querying-microsoft-sql-server/2013/09/19/how-to-split-a-string-by-delimited-char-in-sql-server/

    一旦你有了它,你就可以使用带有 LIKE 的 JOIN:

    SELECT 
      *
    FROM 
      Products p
    INNER JOIN dbo.fnSplitString
               (
                 SELECT TOP 1 Gift.Name FROM Gift WHERE Id = 65
               ) sub ON p.Name LIKE '%' + sub.splitdata + '%'
    

    (我确定这不是 100% 正确的语法。)

    【讨论】:

    • 和我的回答一样。可以直接加入dbo.fnSplitString,无需“SELECT * FROM”。
    • 好消息——已更新。我不明白这与您的答案有何相同。
    • @TabAlleman 我想说的是,你不会得到正确的结果,因为在LIKE 语句中,你最终会得到p.Name LIKE %(a bunch of strings from the split table)%。本质上,您需要找到一种方法来形成查询,例如:p.NAME like %word1' OR p.NAME like %word2' OR p.NAME like %word3' 等等
    • @C.J.同意——但是,连接到表值函数的结果将允许这样做。所以这个答案应该有效。
    • CJ,拆分函数不能这样工作,它返回一个表,其中每个单词都有一列和一行,而不是每个单词都有一行和一列。我的解决方案与 Phil 的完全一样,只是我没有写出 SQL 外观的示例。
    【解决方案4】:

    这会将由一个空格分隔的两个单词的字符串分割成单个单词

    declare @s nvarchar (30)='toy gun'
    select LTRIM(SUBSTRING(@s, CHARINDEX(' ',@s)+1,len(@s)))
    select LTRIM(SUBSTRING(@s, 0,CHARINDEX(' ',@s)+1))
    

    也许这会有所帮助。虽然从任何角度看起来都很丑......

    【讨论】:

    • OP 确实提到了这个词可以是 2 或更多,那么你怎么知道你需要写多少次 select 语句?
    【解决方案5】:

    如果您启用了全文索引,那么使用FREETEXT 查询会产生您想要的结果。您可以通过运行以下查询来检查全文是否已启用:

    SELECT FULLTEXTSERVICEPROPERTY('IsFullTextInstalled')
    

    如果以上返回 1,那么你就可以走了。如果返回 0,则搜索您的 SQL Server 版本的安装说明。这是设置全文索引http://blog.sqlauthority.com/2008/09/05/sql-server-creating-full-text-catalog-and-index/的好指南。

    设置完成后,您可以使用以下代码执行所需的搜索:

    Declare @searchString nvarchar (100);
    
    Select top 1 @searchString = Gift.Name FROM Gift WHERE Id=65;
    
    Select * From Products Where FREETEXT (Name, @searchString);
    

    【讨论】:

      【解决方案6】:

      在 Gift.name 上使用拆分函数,生成单字名称表,并链接到 Product.Name LIKE '%'+SplitFunctionTable.Name+'%' 上的该表。

      如果您的数据库中还没有拆分功能,Google 可以向您展示一些。

      【讨论】:

      • 这没有帮助,你不能有 `LIKE %(该表中的每个单词)%'
      • 另外,SQL 中没有“拆分”功能,除非您自己创建一个。你能得到的最接近的是SUBSTRING
      • 对不起CJ,你错了。 1) 你绝对可以 JOIN ... ON ... LIKE,这将对表的该列中的每一行执行 LIKE 操作。 2)您是否错过了我回答的第二部分,我告诉 OP 如何为 SQL 找到拆分函数?抱歉,如果有人认为我暗示该功能是内置的。您可能想取消您的反对票。
      猜你喜欢
      • 2016-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-05
      • 1970-01-01
      • 2018-07-23
      • 2022-01-13
      • 1970-01-01
      相关资源
      最近更新 更多