简体   繁体   中英

MYSQL many-to-many relationship questions

Below are my tables structure :

posts table:
---------------------
|id|title|body|etc..|
---------------------

tags table:
---------------
|id|name|etc..|
---------------

post_tag table (the pivot table):
-------------------
|id|post_id|tag_id|
-------------------

As you can see, many posts can have many tags and vice versa. What I'm asking is how to query related posts based on how many tags they have in common? For example, if I have some posts like the following :

  1. This is post one with tags: #sql, #nosql, #database
  2. This is post two with tags: #sql, #nosql
  3. This is post three with tags : #database
  4. This is post four with tags : #stackoverflow

How to query posts that are related (having common tags) with post 1 and order the result based on the number of tags they have in common? I've tried the following query :

SELECT p.* 
FROM posts p 
INNER JOIN post_tag pt ON p.id = pt.post_id 
INNER JOIN tags t on pt.tag_id = t.id 
WHERE t.id IN (
    SELECT t.id 
    FROM tags t 
    INNER JOIN post_tag pt ON t.id = pt.tag_id 
    INNER JOIN posts p ON pt.post_id = p.id 
    WHERE p.id = ?
) AND p.id != ? LIMIT 8

It worked but will return duplicates if the posts share more than one tags. Also, I don't know how to order the result based on the number of tags they have in common. That's all, and thanks in advance!

You could join and aggregate as follows:

select p1.id, p2.id, count(*) nb_tags_in_common
from posts p1
inner join post_tag pt1 on pt1.post_id = p1.id
inner join post_tag pt2 on pt2.tag_id = pt1.tag_id
inner join posts p2 on p2.id = pt2.post_id
group by p1.id, p2.id
order by count(*) desc

You can simplify the query like this:

SELECT post_tag.post_id
FROM post_tag
WHERE post_tag.post_id <> 1 AND post_tag.tag_id IN (
    SELECT tag_id
    FROM post_tag
    WHERE post_id = 1
)
GROUP BY post_tag.post_id
ORDER BY COUNT(post_tag.tag_id) DESC
LIMIT 8

And join the results with the posts table if necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM