Sql选择匹配给定列的多个单词的记录

时间:2015-05-07 04:36:37

标签: mysql sql select

假设我有一个表格列出了一些列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上,我将打破系统的“一致性”所以对于“Item”我的意思是产品)

  • 标题实际上是在一个单独的表上,所以在实际场景中它是在一个连接表上

2 个答案:

答案 0 :(得分: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专家,所以你可能不得不捣乱一点点。此外,如果标题不是唯一的,那么选择&按主键和标题分组。

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

我不认为这已经完全解决了你的问题,但我希望它可以帮助你实现目标。

答案 1 :(得分:0)

我使用过这里讨论的方法: 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