进入最匹配的关系

时间:2017-08-17 13:59:09

标签: mysql sql laravel eloquent

我试图创造一些"推荐"基于具有最匹配标签的帖子的功能。

我得到了这样的布局:

帖子

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的那个。

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

1 个答案:

答案 0 :(得分:1)

你的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