Php SQL选择具有类似标记的帖子

Php SQL选择具有类似标记的帖子,php,mysql,sql,database,mariadb,Php,Mysql,Sql,Database,Mariadb,在我的房间里有一张桌子叫 “职位”与 一个叫做“标签”的 还有一个叫做post_标签 id, tag id、post\u id、tag\u id 我想完成的事情是从“posts”表中获得3篇文章,它们与页面上当前显示的文章具有最多的共同标记 我被困在这里不知道从哪里开始 编辑 Posts id | username_id | title | text | image_url | url 1 1

在我的房间里有一张桌子叫

“职位”与

一个叫做“标签”的

还有一个叫做post_标签

id, tag
id、post\u id、tag\u id

我想完成的事情是从“posts”表中获得3篇文章,它们与页面上当前显示的文章具有最多的共同标记

我被困在这里不知道从哪里开始

编辑

Posts

id | username_id |   title   |    text     |       image_url      |           url

 1        1         example    example_text  localhost/image.jpg     localhost/first-post
 2        1         example1   example_text  localhost/image1.jpg    localhost/second-post
 3        1         example2   example_text  localhost/image2.jpg    localhost/third-post
 4        1         example4   example_text  localhost/image4.jpg    localhost/fourth-post
...      ...          ...          ...                ...                     ...
...      ...          ...          ...                ...                     ...


Tags

id | tag

 1   herbs
 2   flower
 3   rose

Post_tags

id | post_id | tag_id

 1      1        1
 2      1        2
 3      1        3
 4      2        1
 5      3        1
 6      3        2
 7      4        1
 8      4        2
 9      4        3        
我想返回一个包含
posts.title
posts.image\u url
的数组,选择与当前帖子相同的
post\u标记最多的帖子。tag\u id

正如你所看到的,如果我们采取后n。1作为所选职位,职位n。4与它有最多的共同标签,第三个位置是第二个位置,第二个位置是第二个位置

example4 | localhost/image4.jpg
example3 | localhost/image3.jpg
example2 | localhost/image2.jpg

我希望我说得更清楚。谢谢。

如果它能满足您的需求,请检查此项。然后您可能需要优化查询

SELECT
t1.*
FROM posts t1,
(
    SELECT
    post_id
    FROM post_tags t2
    WHERE
    tag_id IN (SELECT tag_id FROM post_tags WHERE post_id = $CURRENT_POST_ID)
    AND NOT post_id = $CURRENT_POST_ID
    GROUP BY post_id
    ORDER BY COUNT(tag_id) DESC
    LIMIT 3
) t2
WHERE
t1.id = t2.post_id
根据要求,查询说明:

  • 为了找到与“家长”帖子共享最多标签的前3篇帖子,我们首先需要获得“家长”拥有的标签列表=>
    从post\u标签中选择标签id,其中post\u id=1
  • 然后,通过在包含帖子ID和标签的表中添加条件
    tag\u ID(列表\u标签\u ID\u来自\u SUB\u选择上面显示的\u)来搜索包含至少一个标签的帖子。
  • 现在我们知道了哪些帖子与“parent”共享至少一个标记,因此我们可以计算它们实际上共有多少个标记,并按其排序=>
    orderbycount(*)DESC
  • 因为“parent”post也“共享”这些标记,并且我们不希望他出现在我们的结果中,所以我们给出了额外的条件,排除“parent”的ID=>
    WHERE p.ID!=1
  • 最后,我们将结果集限制为3行,因为我们只需要前3行<代码>限制3
  • 选择计数不是必需的,它只是指出它所计数的
    count(*)是多少个常用标记

  • 这将只获得
    post\u id
    值:

    SELECT  x.post_id
        FROM  
        (
            SELECT  b.post_id
                FROM  Post_tags a
                JOIN  Post_tags b USING(tag_id)
                WHERE  a.post_id = 1234
                  AND  b.post_id != a.post_id
        ) x
        GROUP BY  x.post_id
        ORDER BY  COUNT(*) DESC
        LIMIT  3;
    
    关于设计更好的映射表(Post_标记)。这将为该表提供最佳索引

    要获取有关这3篇文章的更多信息,请执行以下操作:

    SELECT  p.*
        FROM  
        (
            SELECT  x.post_id
                FROM  
                (
                    SELECT  b.post_id
                        FROM  Post_tag a
                        JOIN  Post_tag b USING(tag_id)
                        WHERE  a.post_id = 1234
                          AND  b.post_id != a.post_id 
                ) AS x
                GROUP BY  x.post_id
                ORDER BY  COUNT(*) DESC
                LIMIT  3 
        ) AS y
        JOIN  Posts AS p  ON p.id = y.post_id;
    

    添加示例表数据和预期结果。(以及格式良好的文本)同时向我们展示您当前的查询尝试。请解释您的查询是如何工作的,以便其他人可以从中学习。谢谢
    SELECT  x.post_id
        FROM  
        (
            SELECT  b.post_id
                FROM  Post_tags a
                JOIN  Post_tags b USING(tag_id)
                WHERE  a.post_id = 1234
                  AND  b.post_id != a.post_id
        ) x
        GROUP BY  x.post_id
        ORDER BY  COUNT(*) DESC
        LIMIT  3;
    
    SELECT  p.*
        FROM  
        (
            SELECT  x.post_id
                FROM  
                (
                    SELECT  b.post_id
                        FROM  Post_tag a
                        JOIN  Post_tag b USING(tag_id)
                        WHERE  a.post_id = 1234
                          AND  b.post_id != a.post_id 
                ) AS x
                GROUP BY  x.post_id
                ORDER BY  COUNT(*) DESC
                LIMIT  3 
        ) AS y
        JOIN  Posts AS p  ON p.id = y.post_id;