10

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

如果搜索输入字段是“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

关键字的数量可能会更高,所以我可能需要更多的“喜欢”。“钥匙”的数量也可以增加:)

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

4

3 回答 3

6

如果您启用了SQLite FTS3 和 FTS4 扩展,那么您可以利用全文搜索 (FTS) 功能。您需要将表重新创建p_extra_fieldsVIRTUAL表。然后您可以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;

这里也有很好的信息。单击此处在 SQL Fiddle 上查看它的实际效果。

于 2013-08-24T23:31:51.010 回答
4

我认为这个where条款更简单:

  WHERE x.type = "1" and
        x.key in ('model', 'color', 'make') and
        (x.value like '%foo%' or x.value like '%bar%')
于 2013-08-24T23:23:51.277 回答
0

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

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

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"

于 2018-03-01T11:22:02.623 回答