StoredProcedure
このようにして行う必要があります
CREATE PROCEDURE `friend_list`(user_id INT, MaxLevel INT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE LLevel, LCount INT DEFAULT 0;
DROP TABLE IF EXISTS tmp_friends;
CREATE TEMPORARY TABLE tmp_friends
SELECT user1_id AS friend_id, LLevel AS friend_level
FROM friends
WHERE user2_id = user_id
UNION
SELECT user2_id, LLevel
FROM friends
WHERE user1_id = user_id;
SELECT COUNT(*) INTO LCount FROM tmp_friends;
DROP TABLE IF EXISTS tmp_fr;
WHILE ( LCount > 0 ) AND ( LLevel < MaxLevel ) DO
SET LLevel = LLevel + 1;
CREATE TEMPORARY TABLE tmp_fr
SELECT user1_id as friend_id, LLevel as friend_level
FROM friends
WHERE user2_id IN ( SELECT friend_id FROM tmp_friends WHERE friend_level = LLevel - 1 );
INSERT INTO tmp_fr
SELECT user2_id as friend_id, LLevel as friend_level
FROM friends
WHERE user1_id IN ( SELECT friend_id FROM tmp_friends WHERE friend_level = LLevel - 1 );
DELETE FROM tmp_fr
WHERE friend_id IN ( SELECT friend_id FROM tmp_friends )
OR friend_id = user_id;
SELECT COUNT(*) INTO LCount FROM tmp_fr;
INSERT INTO tmp_friends
SELECT * FROM tmp_fr;
DROP TABLE tmp_fr;
END WHILE;
SELECT *
FROM tmp_friends
ORDER BY friend_level;
DROP TABLE tmp_friends;
END
id
ユーザーのと友達レベル(0は直接、1は友達の友達、...)を含む結果セットを取得します。
user_idと最大フレンドレベルを渡すだけです
CALL friend_list( 1, 10 );
このテーブル構造を使用しました
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `friends` (
`user1_id` int(11) unsigned NOT NULL,
`user2_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`user1_id`,`user2_id`),
KEY `fk_friends_users2` (`user2_id`),
CONSTRAINT `fk_friends_users2` FOREIGN KEY (`user2_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_friends_users1` FOREIGN KEY (`user1_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;