1

我正在做一个电子商店,所以我有 3 张桌子:

1)goods

id      | title
--------+----------- 
1       | Toy car
2       | Toy pony
3       | Doll

2)tags

id      | title
--------+----------- 
1       | Toy
2       | Boys
3       | Girls

3)links

goods_id| tag_id
--------+----------- 
1       | 1
1       | 2
2       | 1
2       | 2
2       | 3
3       | 3

所以我需要使用这样的算法打印相关商品:使用标签获取与所选商品最相似的商品。大多数标签是相互的 - 最合适的项目是

所以结果goods#1应该是goods#2goods#3

对于goods#2: goods#1,goods#3

对于goods#3: goods#2,goods#1

而且我不知道如何通过一次查询获得按相互标签计数排序的类似商品

4

3 回答 3

3

此查询将返回具有最大公共标签数的所有项目:

SET @item = 1;

SELECT
  goods_id
FROM
  links
WHERE
  tag_id IN (SELECT tag_id FROM links WHERE goods_id=@item)
  AND goods_id!=@item
GROUP BY
  goods_id
HAVING
  COUNT(*) = (
    SELECT
      COUNT(*)
    FROM
      links
    WHERE
      tag_id IN (SELECT tag_id FROM links WHERE goods_id=@item)
      AND goods_id!=@item
    GROUP BY
      goods_id
    ORDER BY
      COUNT(*) DESC
    LIMIT 1
  )

在此处查看小提琴。

或者这个将返回所有项目,即使是那些没有共同标签的项目,按共同标签的数量排序:

SELECT
  goods_id
FROM
  links
WHERE
  goods_id!=@item
GROUP BY
  goods_id
ORDER BY
  COUNT(CASE WHEN tag_id IN (SELECT tag_id FROM links WHERE goods_id=@item) THEN 1 END) DESC;
于 2013-06-28T18:12:28.863 回答
1

当您要展示商品 id = 2 的商品时

SELECT DISTINCT
  goods.*
FROM
  goods
  LEFT JOIN links ON links.goods_id = goods.id
WHERE links.tag_id IN (SELECT links.tag_id 
                       FROM links
                       WHERE links.goods_id = 2)

当你不包括goods_id = 2

SELECT DISTINCT
  goods.*
FROM
  goods
  LEFT JOIN links ON links.goods_id = goods.id
WHERE links.goods_id != 2 AND links.tag_id IN (SELECT links.tag_id 
                       FROM links
                       WHERE links.goods_id = 2)

可以在http://sqlfiddle.com/#!2/0fb60/38上看到

于 2013-06-29T15:29:21.147 回答
-1

一些帮助:

假设您看起来与商品最相似#1

SELECT a.*  
FROM (SELECT * FROM goods WHERE id <> 1) a 
LEFT JOIN (SELECT z.goods_id, count(*) as total
          FROM links z
          WHERE z.goods_id <> 1 AND
          z.tag_id in (SELECT DISTINCT tag_id from links where goods_id = 1)
          GROUP BY z.goods_id) b 
ON a.id = b.goods_id
ORDER by b.total DESC

但是,我认为您可以尝试一些不同的东西。您可以按常见标签的比例排序,而不是按常见标签的数量排序。这样一来,您将避免标签较多的产品总是出现在排名顶部的事实,即使相对常见的标签并不多。

于 2013-06-28T18:11:29.823 回答