如何在SQL

时间:2017-08-22 04:55:23

标签: mysql

我的数据集:

CREATE TABLE `users` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(50) NOT NULL COLLATE `utf8mb4_bin`,
  PRIMARY KEY (`id`)
)
COLLATE=`utf8mb4_bin`
ENGINE=InnoDB
;

CREATE TABLE `friends` (
    `friend_one` INT(11) NOT NULL,
    `friend_two` INT(11) NOT NULL,
    `status` INT(11) NULL DEFAULT NULL,
    `requested_id` INT(11) NOT NULL,
    UNIQUE INDEX `friend_one_friend_two` (`friend_one`, `friend_two`),
    INDEX `IDX_FRIEND_ONE` (`status`, `friend_one`, `friend_two`),
    INDEX `IDX_FRIEND_TWO` (`status`, `friend_two`, `friend_one`),
    CONSTRAINT `FK_FRIEND_ONE` FOREIGN KEY (`friend_one`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
    CONSTRAINT `FK_FRIEND_TWO` FOREIGN KEY (`friend_two`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE=`utf8mb4_bin`
ENGINE=InnoDB
;

INSERT INTO users(id, username) VALUES
(1, 'A'),
(2, 'B'),
(3, 'C');

INSERT INTO friends(friend_one, friend_two, status, requested_id) VALUES 
(1, 2, 1, 1),
(1, 3, 1, 1);

相同的SQL小提琴:http://sqlfiddle.com/#!9/10dba9/5

我想从我朋友的桌子上找朋友的朋友。

我强制执行friend_one总是小于friend_two(1< 2) 并始终假设1 - > 2朋友的关系是2 - > 1使用状态键(0表示待处理,1表示朋友)

现在我希望得到朋友的朋友: 1 - > 2和1 - > 3是朋友,我希望推荐2到3或3到2的说法 "你有一个共同的朋友1!"

这就是我结交朋友的方式

SELECT u.id, u.username, f.friend_one, f.friend_two, f.status, f.requested_id
  FROM users u 
  JOIN friends f 
    ON f.status = 1 AND f.friend_one = 1 AND f.friend_two = u.id
 UNION ALL
SELECT u.id, u.username, f.friend_one, f.friend_two, f.status, f.requested_id
  FROM users u 
  JOIN friends f 
    ON f.status = 1 AND f.friend_two = 1 AND f.friend_one = u.id



更新1

我提到了这一点,但看起来表格没有强制执行id 1 < id 2 Finding mutual friend in one way relationship table

更新2

我想我在这里找到了解决方案 Sql to get all the friends of friends who's not my friend

我不知道这个内连接是否会影响性能。在这种情况下有没有办法使用连接?

SELECT u.id, u.user_id, u.username, F2.friend_two, F2.status
  FROM friends F 
  JOIN friends F2 
    ON F.friend_two = F2.friend_one 
  JOIN users u 
    ON u.id = F2.friend_two
 WHERE F2.friend_two NOT IN (SELECT friend_two 
                               FROM friends
                              WHERE friend_one = 2) 
   AND F.friend_one = 2 
   AND F2.`status` < 1 
    OR NULL
 GROUP BY F2.friend_two
 ORDER BY F2.friend_two;

0 个答案:

没有答案