2013-06-28 4 views
0

Пусть следующие таблицы:комплекс SQL-запрос для получения рекомендаций

User 
---- 
id 
name 

Rating 
------ 
userid 
movieid 
value 

Movie 
----- 
id 
title 

movie_genre 
----------- 
movieid 
genreid 

genre 
----- 
id 
value 

Я думаю, что внешние ключи очевидны здесь. Запрос, который я ищу, это следующее:

Movie A - это фильм жанра X, который и я, и некоторые другие пользователи оценили по значению 5. Я хочу, чтобы Movie B также был записан в жанре X, который оценивался пятью за другим упомянутых выше пользователей.

И я серьезно не могу его найти ... Количество объединений не обязательно является проблемой кстати, их может быть много.

EDIT: В случае, если я не понял. Идея здесь в том, что люди могут иметь похожий вкус в одном жанре, но совсем другой вкус в другом жанре. Мне нравятся фильмы, которые нравятся другим людям, у которых одинаковый вкус в этом жанре.

ответ

0

Это то, что я думаю, что вы ищете:

Учитывая пользователь John, найти все фильмы B такое, что существует фильм А, пользователь Саймон и жанр G, где:

  • Джон рейтинг фильма Аа 5
  • Саймон рейтинг фильма Аа 5
  • Саймон не Джон
  • Саймон рейтинг фильма в 5
  • фильм А жанровой G
  • фильм Б жанра G

Выражаясь таким образом, я думаю, что это довольно легко придумать с запросом:

select B.* 
from user John 
join rating JohnA on JohnA.userid = John.id and JohnA.value = 5 
join movie A on A.id = JohnA.movieid 
join rating ASimon on ASimon.movieid = A.id and ASimon.value = 5 
join user Simon on Simon.id = ASimon.userid and Simon.id <> John.id 
join rating SimonB on SimonB.userid = Simon.id and SimonB.value =5 
join movie B on B.id = SimonB.movieid 
join movie_genre Agenre on Agrenre.movieID = A.id 
join genre G on G.id = Agenre.genreid 
join movie_genre Bgenre on Bgenre.genreid = G.id and Bgenre.movieid = B.id 

База данных выбора будет вероятно, оптимизируйте это, чтобы удалить некоторые соединения, но нам действительно нужны отношения (рейтинги), а не промежуточные объекты (фильм A, пользователь Simon и жанр G):

select B.* 
from user John 
join rating JohnA on JohnA.userid = John.id and JohnA.value = 5 
join rating ASimon on ASimon.movieid = JohnA.movieid and ASimon.value = 5 and ASimon.userid <> John.id 
join rating SimonB on SimonB.userid = ASimon.userid and SimonB.value =5 
join movie B on B.id = SimonB.movieid 
join movie_genre Agenre on Agrenre.movieID = A.id 
join movie_genre Bgenre on Bgenre.genreid = Agenre.genreid and Bgenre.movieid = B.id