ipkiss
ipkiss

Reputation: 13671

Find related topics in mysql?

I have database as follows:

Post {id, title}
Topic {id, name}
Post_Topic {PostId, TopicId}

Since each post may have many topics, so I want to get related topics based on the number of times they appears in posts together. For example:

post 1 has topics {database, mysql, mobile}
post 2 has topics {database, mysql, android}
post 3 has topics {database, mysql, algorithm}
post 4 has topics {database, algorithm, web programming}

Based on the above data, if the input is database, then related topics should be displayed in order:

mysql (appears 3 times with database)
algorithm (appears 2 times with database)
android
mobile

How can I write the sql to achieve that?

Upvotes: 0

Views: 103

Answers (2)

Unlink
Unlink

Reputation: 1003

Try this one

SELECT topic_name FROM (SELECT COUNT(*) as cnt, t.id, t.topic_name 
FROM Topic t 
JOIN Post_Topic pt ON (pt.TopicId = t.id)
WHERE pt.PostId IN (
    SELECT pt2.PostId FROM Post_Topic pt2 JOIN Topic t2 ON (pt2.TopicId = t2.id) WHERE t2.topic_name= 'database')
GROUP BY t.id, t.topic_name) as S
WHERE topic_name != 'database'
ORDER BY cnt DESC

Upvotes: 0

Raphaël Althaus
Raphaël Althaus

Reputation: 60503

You may find a better way (not great to have a condition two times), but, with a join and an exists clause, you'll get what you want.

select t_id, t.title, count(*) as cnt
from post_topic pt
join topic t on t.id = pt.t_id

where exists (select null
              from post_topic pt1
              join topic t1 on pt1.t_id = t1.id
              where t1.title = 'database'  and p_id = pt.p_id)
and t.title <> 'database'
group by  t_id, t.title
order by cnt desc;

see Sqlfiddle

Upvotes: 1

Related Questions