MYSQL与多个WHERE最接近匹配

时间:2011-03-04 14:51:44

标签: php mysql

在我的数据库中,我有一个包含产品的表格和另一个包含与每种产品相关联的标签的表格。

当用户查看产品页面时,我想向他正在查看的产品展示最“相关”(或最接近)的产品。

因此,假设产品标有5种不同的标签。我想获得具有相同5个标签的产品,然后是具有相同5个标签中的4个标签的产品,然后是具有相同5个标签中的3个标签的产品等等......

要做到这一点,我猜我必须创建一个或多个MYSQL查询,但我甚至不知道从哪里开始。

匹配相同的5个标签很简单,我可以使用WHERE tag ='?' AND tag ='?'...但我怎样才能得到另一个(4 / 5,3 / 5,2 / 5,1 / 5)?

非常感谢任何帮助!

干杯 史蒂芬


EDITS

@Orbits:我的标签都在不同的行上......如果不是,我可能会进行文本匹配,但情况就是如此。标记行由(id,tag,product_id)

组成

@ cusimar9:不同的表格,如帖子中所述:P

@vbence:我相信它尽可能简单..这是......但我没有连接表

产品:

CREATE TABLE `products` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  ...
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

TAGS:

CREATE TABLE `tags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(70) NOT NULL,
  `product_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=116 ;

4 个答案:

答案 0 :(得分:3)

当然,字符串文字“Tag1”必须替换为您的标记。

SELECT products.id, COUNT(tags.id) AS match_level
FROM products
    LEFT JOIN tags ON tags.product_id = product.id
WHERE tags.type IN ('Tag1', 'Tag2', 'Tag3', 'Tag4', 'Tag5')
GROUP BY products.id
ORDER BY match_level DESC

如果您还没有这样的索引,请将其添加到tags表中。没有索引,你就是在浪费资源。很开心。

CREATE INDEX multimatch ON tags (type, product_id);

答案 1 :(得分:1)

SELECT A.*
  FROM ( SELECT P.*,
                P.Tag LIKE '%a%' AS Tag1,
                P.Tag LIKE '%b%' AS Tag2,
                P.Tag LIKE '%c%' AS Tag3,
                P.Tag LIKE '%d%' AS Tag4,
                P.Tag LIKE '%e%' AS Tag5
           FROM `products` P
          WHERE P.Tag LIKE '%a%' 
             OR P.Tag LIKE '%b%' 
             OR P.Tag LIKE '%c%'
             OR P.Tag LIKE '%d%' 
             OR P.Tag LIKE '%e%'
       ) A
 ORDER BY A.Tag1+A.Tag2+A.Tag3+A.Tag4+A.Tag5 DESC

答案 2 :(得分:1)

Simples:

SELECT related.id, count(*) as matches
FROM products related,
     tags rel_tags,
     tags this_tags
WHERE this_tags.product_id=$product_id_for_this_product
AND this_tags.type=rel_tags.type
AND rel_tags.product_id<>this_tags.product_id
AND rel_tags.product_id=related.id
GROUP BY related_id
ORDER BY count(*) DESC

答案 3 :(得分:0)

select products.id, count(*) as matches
from products 
inner join tags on products.id = tags.product_id
inner join (
    select t.id
    from products p
    inner join tags t on p.id = t.product_id
    where p.id = $product_id
) product_tags on tags.id = product_tags.id
group by products.id
order by products.id desc