【问题标题】:sql query to determine the most similar goods by tagssql查询通过标签确定最相似的商品
【发布时间】:2013-06-28 17:55:17
【问题描述】:

我正在做一个电子商店,所以我有 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#2,goods#3

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

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

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

【问题讨论】:

    标签: mysql sql join


    【解决方案1】:

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

    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
      )
    

    请看小提琴here

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

    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;
    

    【讨论】:

    • 不错的工具!我不知道小提琴。对我很有用,谢谢发帖。
    • 谢谢!但它只返回小提琴中的第一个类似项目......不是全部
    • 您的查询很好,但如果我们删掉第二部分效果更好,请查看,据我所知,这效果更好:sqlfiddle.com/#!2/0fb60/8/0
    • @dimaninc 请看看我更新的查询,我不确定,但也许你正在寻找我的最后一个查询
    • 我使用了在我的 sqlfiddle 链接中完美运行的情况。非常感谢您的帮助,伙计!
    【解决方案2】:

    当您要展示商品 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上看到

    【讨论】:

      【解决方案3】:

      一些帮助:

      假设您看起来与商品最相似#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
      

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

      【讨论】:

        猜你喜欢
        • 2014-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多