MYSQL вопросы отношения многие ко многим - PullRequest
0 голосов
/ 11 декабря 2019

Ниже приведена структура моих таблиц:

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

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

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

Как видите, многие сообщения могут иметь много тегов и наоборот. То, что я спрашиваю, это как сделать запрос к связанным сообщениям, основываясь на том, сколько у них общих тегов? Например, если у меня есть несколько постов, таких как:

  1. Это пост с тегами: #sql, #nosql, # database
  2. Это пост с тегами: #sql, # nosql
  3. Это сообщение три с тегами: # database
  4. Это сообщение четыре с тегами: # stackoverflow

Как запросить сообщения, связанные с(с общими тегами) с постом 1 и упорядочить результат по количеству общих тегов? Я пробовал следующий запрос:

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

Это сработало, но будет возвращать дубликаты, если сообщения имеют более одного тега. Кроме того, я не знаю, как упорядочить результат по количеству общих тегов. Вот и все, и заранее спасибо!

Ответы [ 2 ]

1 голос
/ 11 декабря 2019

Вы можете упростить запрос следующим образом:

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

И при необходимости объединить результаты с таблицей сообщений.

1 голос
/ 11 декабря 2019

Вы можете объединиться и объединиться следующим образом:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...