这两个表来自一个类似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建议一个他们可能感兴趣的用户列表。我认为一个启发式的方法是为所有y用户y显示x,其中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 ;
2条答案
按热度按时间ymdaylpp1#
我认为最基本的查询是让所有的“观察者”与给定的观察者共享三个“主题”:
查询的其余部分只是加入名称,以适应将名称用作引用而不是id的范例。
sulc1iza2#
请考虑下面的重构sql代码(未经测试,没有数据),以便在存储过程中使用。