Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

complex SQL query, many to many

Tags:

sql

mysql

Complex for me as I am newbie in SQL.

I have three tables - Peoples, Interests and Peoples_Interests (many-to-many) - that are connected in the following way:

People has many Interests through Peoples_Interests
Interest has many Peoples through Peoples_Interests

I need to propose suggestions to Peoples with most similar to them Peoples, which is based on amount of similar Interests. So for example:

I am interested in baseball, football and volley. I should get suggestion with another user that have as many similar interests as possible. People with 3/3 occurrences should be what I need if they exist (if not - 2/3 and such).

So I need a query that output will consist of sorted by interests similarity Peoples.

UPDATE: Db structure:

Interests
id
name - string

Peoples
id
email

Peoples_Interests
interests_id
peoples_id

Thank you.

like image 288
Call 'naive' True Avatar asked Jun 05 '11 12:06

Call 'naive' True


People also ask

How do you write a SQL query for many-to-many relationships?

When you need to establish a many-to-many relationship between two or more tables, the simplest way is to use a Junction Table. A Junction table in a database, also referred to as a Bridge table or Associative Table, bridges the tables together by referencing the primary keys of each data table.

What is an advanced SQL query?

According to this reply, advanced SQL covers selecting columns, aggregate functions like MIN() and MAX() , the CASE WHEN statement, JOINs , the WHERE clause, GROUP BY , declaring variables, and subqueries.


1 Answers

Something like this.

Select people.id, people.name, count(interest.id)
from people
left join people_interests on people.id = people_interests.peopleid 
left join interests on people_interests.interestid = interests.interest.id
where interests.id in (select id from interests where interests.peopleid = @inputuserid)
group by people.id, people.name
order by count(interest.id)

In english (which may or may not make it clearer.)

  • Select the person's name and the number of interests they share
  • From the people table
  • Join the interests table such that that table
  • Is only the interests of the person we are trying to match.
  • (group by people
  • and order by the number of interests that match.)

Updated without the sub query but less clear

Select people.id, people.name, count(interest.id)
from people
left join people_interests on people.id = people_interests.peopleid 
left join interests on people_interests.interestid = interests.interest.id
inner join interest i2 on (interests.id = i2.id and i2.people_id = @inputuserid)
group by people.id, people.name
order by count(interest.id)
like image 164
Hogan Avatar answered Sep 23 '22 15:09

Hogan