我正在尝试根据具有最匹配标签的帖子创建一点“推荐”功能。

我有这样的布局:

帖子

id
---
1
2
3
4


post_tags

post_id  | tag_id
---------+---------
1        | 1
1        | 2
2        | 2
2        | 3
2        | 4
3        | 1
3        | 2
3        | 4
4        | 5


标签

id
----
1
2
3
4
5


因此,如果我要检索ID为1的帖子的推荐,则该列表应

3(2/2场比赛)
2(1/2场比赛)
4(0/2场比赛)

到目前为止,我的查询看起来像这样:

 SELECT DISTINCT
    p.id,
    p.title,
    count(*) as cnt
 FROM
    posts p
 INNER JOIN posts_tags pt ON pt.post_id= p.id
 INNER JOIN tags t ON pt.tag_id = t.id
 WHERE
    t.id IN (
        SELECT
            pt.tag_id
        FROM
            posts_tags pt
        WHERE
            pt.post_id = '30213'
    )
 GROUP BY
    t. NAME
 order by count(*) desc
 LIMIT 0, 4


我知道DISTINCT由于计数而无法工作,但是我想看看他的计数,所以结果看起来像这样:

 4  Foo 4881
 4  Foo 2560
 11 Bar 2094
 12 Baz 1998


所以发生了什么事?通常,它会统计标签的出现次数。因此,显然“ Post 1”的第一个关联标签是4881关联,然后拉出匹配的第一个条目……具有最低ID的条目。

我看到了问题,但无法解决。

最佳答案

您的group by没有任何意义。您想按帖子而不是标签进行汇总:

SELECT p.id, p.title, count(*) as cnt
FROM posts p INNER JOIN
     posts_tags pt
     ON pt.post_id = p.id
WHERE pt.tag_id IN (SELECT pt2.tag_id
                    FROM posts_tags pt2
                    WHERE pt2.post_id = 30213
                   )
GROUP BY p.id, p.title
ORDER BY count(*) desc
LIMIT 0, 4;


这不会返回0。如果那很重要,则需要使用LEFT JOIN而不是WHERE . . . IN . . .

也:


SELECT DISTINCT几乎从未与GROUP BY一起使用。很难(但并非没有可能)提出一个用例。
您不需要tags表,因此我将其删除。
不要在数字周围使用单引号。我猜post_id确实是一个数字。
该修复程序在GROUP BY中。

关于mysql - 具有最匹配关系的条目,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45737188/

10-09 07:11