Это две таблицы из части предполагаемой базы данных, похожей на Twitter, где пользователи могут следить за другими пользователями. Поле User.name является уникальным.
mysql> select uID, name from User;
+-----+-------------------+
| uID | name |
+-----+-------------------+
| 1 | Alice |
| 2 | Bob |
| 5 | Iron Maiden |
| 4 | Judas Priest |
| 6 | Lesser Known Band |
| 3 | Metallica |
+-----+-------------------+
6 rows in set (0.00 sec)
mysql> select * from Follower;
+-----------+------------+
| subjectID | observerID |
+-----------+------------+
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
| 6 | 1 |
| 3 | 2 |
| 4 | 2 |
| 5 | 2 |
+-----------+------------+
7 rows in set (0.00 sec)
mysql> call newFollowSuggestionsForName('Bob');
+-------------------+
| name |
+-------------------+
| Lesser Known Band |
+-------------------+
1 row in set (0.00 sec)
Я хочу сделать операцию, которая предложит пользователю X список пользователей, которым они могут заинтересоваться. Я думал, что одной эвристикой может быть показ X для всех y, за которыми следует пользователь y, где X и y следуют как минимум за 3 из тех же пользователей. Ниже приведен SQL-код, который я придумал для этого. У меня вопрос: можно ли сделать это более эффективно или лучше другими способами?
DELIMITER //
CREATE PROCEDURE newFollowSuggestionsForName(IN in_name CHAR(60))
BEGIN
DECLARE xuid INT;
SET xuid = (select uID from User where name=in_name);
select name
from User, (select subjectID
from follower
where observerID in (
select observerID
from Follower
where observerID<>xuid and subjectID in (select subjectID from Follower where observerID=xuid)
group by observerID
having count(*)>=3
)
) as T
where uID = T.subjectID and not exists (select * from Follower where subjectID=T.subjectID and observerID=xuid);
END //
DELIMITER ;