【问题标题】:Multiple LIKE in sqlitesqlite中的多个LIKE
【发布时间】:2013-08-27 18:05:01
【问题描述】:

我正在尝试创建搜索功能。

如果搜索输入字段是“foo bar”,我将其拆分为两个关键字,然后执行以下查询:

SELECT p.* FROM p_extra_fields as x INNER JOIN products as p ON x.product = p.id
  WHERE x.type = "1"
  AND
  (
     (x.key = "model" AND x.value LIKE "%foo%")
  OR (x.key = "model" AND x.value LIKE "%bar%")
  OR (x.key = "color" AND x.value LIKE "%foo%")
  OR (x.key = "color" AND x.value LIKE "%bar%")
  OR (x.key = "make" AND x.value LIKE "%foo%")
  OR (x.key = "make" AND x.value LIKE "%bar%")
  )      

GROUP BY x.product LIMIT 0, 50

关键字的数量可能会更多,所以我可能需要更多的“赞”。 “key”的数量也可以增加:)

有什么方法可以简化这个查询吗?我可以做类似LIKE("%foo%", "%bar%") 的事情吗?

【问题讨论】:

  • 经过大量阅读后,我能够在不安装 REGEXP imp 或 FTS3 和 FTS4 扩展的情况下完成您需要的操作,请查看我的解决方案

标签: sql sqlite search select sql-like


【解决方案1】:

如果您启用了SQLite FTS3 and FTS4 Extensions,则可以利用全文搜索 (FTS) 功能。您需要将p_extra_fields 表重新创建为VIRTUAL 表。然后您可以在搜索词之间插入OR 并使用MATCH 运算符...

SELECT p.* 
FROM p_extra_fields x
JOIN products p ON p.id = x.product
WHERE x.key IN ('model', 'color', 'make')
AND x.type = '1'
AND x.value MATCH 'foo OR bar'
GROUP BY x.product LIMIT 0, 50;

还有很好的信息here。 单击here 在 SQL Fiddle 上查看它的实际效果。

【讨论】:

  • 所以我必须创建一个虚拟表,它是我的p_extra_fields 表的副本?
  • 很好,经过一些研究,无需使用regexmatch 就能做到这一点,请检查我的解决方案:)
  • 重要提示:LIKE("%foo%") 搜索包含 'foo' 的单词; MATCH 'foo' 搜索等于 'foo' 的单词。据我所知,使用 FTS,您无法搜索包含另一个单词的单词
【解决方案2】:

我认为这个where 子句更简单:

  WHERE x.type = "1" and
        x.key in ('model', 'color', 'make') and
        (x.value like '%foo%' or x.value like '%bar%')

【讨论】:

    【解决方案3】:

    我有同样的要求,我正在寻找一种可以匹配 REGEXP "A|B|C" 的机制,这意味着匹配 ABC

    所以最后这是我想出的解决方案:

    WITH words(str, strSubString, hasComma) AS (
      VALUES ('', "foo,bar", 1)
      UNION ALL SELECT
                  SUBSTR(strSubString, 0,
                         CASE WHEN INSTR(strSubString, ',')
                           THEN INSTR(strSubString, ',')
                         ELSE LENGTH(strSubString) + 1 END),
                  LTRIM(SUBSTR(strSubString, INSTR(strSubString, ',')), ','),
        INSTR(strSubString, ',')
          FROM ssgPaths
          WHERE hasComma
      )
    
    SELECT p.* FROM p_extra_fields as x INNER JOIN products as p ON x.product = p.id
    JOIN words AS w ON x.value LIKE '%' || w.str || '%' AND w.str != ''
    WHERE x.type = "1" and x.key in ('model', 'color', 'make');
    

    匹配条件相当于@Gordon的回答:

    WHERE x.type = "1" and
            x.key in ('model', 'color', 'make') and
            (x.value like '%foo%' or x.value like '%bar%')
    

    但这使您可以灵活地根据查询参数动态匹配值(您可以提取出"foo,bar" 作为参数)。

    例如,在不更改查询的情况下,您可以传递 "foo,bar,boo" 并直到匹配类似于正则表达式匹配:"foo|bar|boo"

    【讨论】:

      猜你喜欢
      • 2013-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-22
      • 1970-01-01
      • 2015-08-11
      • 1970-01-01
      相关资源
      最近更新 更多