假设我有一个表格列出了一些列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-1
,n-2
直到2,并在结果集中有一个动态列,其中包含匹配的单词数,因此在此分数的基础上对结果进行排序,是有可能吗?
额外信息:
我无法改变表结构/属性。 (因为我在Magento上,我将打破系统的“一致性”所以对于“Item”我的意思是产品)
标题实际上是在一个单独的表上,所以在实际场景中它是在一个连接表上
答案 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