【问题标题】:Sql select record that match multiple words for a give columnSql 选择与给定列的多个单词匹配的记录
【发布时间】:2015-05-07 04:36:36
【问题描述】:

假设我有一个表格,其中列出了一些带有 title 列的项目

现在给定一个标题为“AAA BBB CCC DDD”的项目,我想检索至少有 n-1 匹配词的所有项目。

目前我正在生成n-1 单词的所有组合(php 端),然后使用 LIKE 进行匹配,所以是这样的:

SELECT
  `e`.`title`
FROM `items` AS `e`
WHERE ((
  (e.title LIKE '%AAA%' AND e.title LIKE '%BBB%' AND e.title LIKE '%CCC%') OR
  (e.title LIKE '%AAA%' AND e.title LIKE '%BBB%' AND e.title LIKE '%DDD%') OR
  (e.title LIKE '%AAA%' AND e.title LIKE '%CCC%' AND e.title LIKE '%DDD%') OR
  (e.title LIKE '%BBB%' AND e.title LIKE '%CCC%' AND e.title LIKE '%DDD%')))

问题

  • 我远不是一个 SQL 大师 :) 有没有比上面的例子更好的方法?

  • 一个额外的要求是搜索带有n-2 字词的项目,以防找不到带有n-1 的项目。 我的想法是找到所有与n-1n-2 匹配的项目,直到 2 并且在结果集中有一个包含匹配单词数的动态列,因此根据这个分数对结果进行排序,这可能吗?

额外信息:

  • 我无法更改表结构/属性。 (我会打破系统“一致性”,因为我在 Magento 上,所以“项目”是指产品)

  • 标题实际上位于单独的表中,因此在实际场景中它位于连接表中

【问题讨论】:

  • 似乎是全文索引的任务
  • 考虑在实际场景中简化了示例查询我在第二个表上有标题所以我必须做一个连接...说我不确定它是什么全文索引但是我确定我不能更改表索引
  • 检查MATCH函数。它有一个适合你的“评分”功能
  • 不幸的是fullindex不可用,所以匹配功能

标签: mysql sql select


【解决方案1】:

它不会很快,但像这样:

SELECT
  `e`.`title`, count(*)
FROM `items` AS `e`
inner join 
(select 'AAA' as search union all select 'BBB' union all select 'CCC') as z
on `e`.`title` like concat('%',`z`.`search`,'%')
group by `e`.`title`
order by COUNT(*) desc

我不是 MySQL 专家,因此您可能不得不稍微考虑一下。此外,如果标题不是唯一的,则按主键和标题选择 & 分组。

如果您的搜索参数已经在表格中,那很好 - 您不必再次选择它们。

我不认为这已经完全解决了你的问题,但我希望它可以帮助你到达那里。

【讨论】:

【解决方案2】:

我使用了这里讨论的方法: Count and Order By Where clause Matches

这里给出一个标题为 AAA BBB CCC 的项目

注意
对于单词排列(因为我们不想重新发明轮子吗?)
我用过这个库http://pyrus.sourceforge.net/Math_Combinatorics.html

我没有发布完整的 php 代码,因为它与问题没有直接关系(它也是基于 Zend 的,只会造成更多混乱)

SELECT item_id
FROM `item` AS `title_match`
WHERE
  (
    (title_match.value LIKE '%AAA%' AND title_match.value LIKE '%BBB%') OR
    (title_match.value LIKE '%AAA%' AND title_match.value LIKE '%CCC%') OR
    (title_match.value LIKE '%BBB%' AND title_match.value LIKE '%CCC%')
  )
ORDER BY CASE WHEN `title_match`.`value` LIKE '%AAA%' THEN 1
         ELSE 0 END +
         CASE WHEN `title_match`.`value` LIKE '%BBB%' THEN 1
         ELSE 0 END +
         CASE WHEN `title_match`.`value` LIKE '%CCC%' THEN 1
         ELSE 0 END
DESC

【讨论】:

    猜你喜欢
    • 2020-12-19
    • 1970-01-01
    • 2022-10-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多