Как вы можете запросить 2 уровня соединений между людьми в одном запросе MySQL? - PullRequest
1 голос
/ 02 августа 2011

У меня есть таблица MySQL со следующей схемой:

+---------+---------+----------------------+------------+
| User ID | Song ID | Recommending User ID | Created On |
+---------+---------+----------------------+------------+
|  1001   |   54    |        1004          | 2011-07-21 |
|  1002   |   23    |        1005          | 2011-07-28 |
|  1002   |   166   |        1001          | 2011-07-31 |
+---------+---------+----------------------+------------+

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

Итак, скажем, мы берем пользователя 1001. 1001 любимая песня с идентификатором 54, которая была рекомендована 1004 7/21. Запрос должен дать 40 баллов при сканировании 1001.

Теперь, что делает это сложным, я хочу добавить второй уровень. Таким образом, для каждого пользователя с 1001 избранным (то есть 1004) я хочу искать его (1004) таким же образом, давая каждому 1004 избранных 20 баллов, при этом все еще вычисляя 1001 * 1008

Просто чтобы уточнить еще раз. Давайте возьмем 1002 в качестве примера:

Computing 1002:
    User 1005 gets 40 pts
    User 1001 gets 40 pts
    Computing 1005
         nothing
    Computing 1001
         User 1004 gets 20 pts
Done

Любая помощь о том, как начать очень ценится:)

* Редактировать: указанный mysql

Ответы [ 2 ]

1 голос
/ 02 августа 2011

Как насчет этого (я называю таблицу, которую вы обрисовали в общих чертах выше "Рекомендации"):

Каждый раз, когда песня помечается как "любимая", нам нужно посмотреть, порекомендовал ли это кто-то другой.Поэтому предположим, что пользователь UserID просто пометил SongID как своего "фаворита".Следующий человек получает 40 баллов:

SELECT Recommending_user_id
FROM Recommendations 
WHERE User_id = [UserID] 
AND Song_id = [SongID]

То, что вы спросили, - это как проверить уровень рекомендаций.Мы можем сделать это с помощью JOIN таблицы Рекомендаций:

SELECT Forty.Recommending_user_id, Twenty.Recommending_user_id
FROM Recommendations Forty
LEFT JOIN Recommendations Twenty
       ON (Forty.Recommending_user_id = Twenty.User_id
       AND Forty.Song_id = Twenty.Song_id)
WHERE Forty.User_id = [UserID] 
  AND Forty.Song_id = [SongID]

LEFT JOIN гарантирует, что, если пользователь с 20 точками не существует, он не нарушит запрос;вы просто получите NULL для Twenty.Recommending_user_id.

Обратите внимание, что вы можете присоединиться снова, чтобы дать 10 баллов на третий уровень, если хотите.:)

0 голосов
/ 02 августа 2011

Есть много способов, но у меня есть всего 5 минут, прежде чем я пойду к своей подруге.Итак, вот один из возможных способов ... (Нет, она не взорвать)

SELECT
  CASE WHEN Mode = 1 THEN [principle].recommending_user_id ELSE [secondary].recommending_user_id END AS user_id,
  SUM(CASE WHEN Mode = 1 THEN 40 ELSE 20 END) AS Score
FROM
  myTable   AS [principle]
LEFT JOIN
  myTable   AS [secondary]
    ON [principle].recommending_user_id = [secondary].user_id
CROSS JOIN
  (SELECT 1 AS MODE UNION ALL SELECT 2) AS Mode
WHERE
  CASE WHEN Mode = 1 THEN [principle].recommending_user_id ELSE [secondary].recommending_user_id END IS NOT NULL
GROUP BY
  CASE WHEN Mode = 1 THEN [principle].recommending_user_id ELSE [secondary].recommending_user_id END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...