我有2张桌子
1) USERS - List of all users
2) FRIENDS - List of users who are friends with each other
我想让所有用户与所有其他用户成为朋友。所以基本上我需要在好友表中插入所有用户信息。
USERS表格列
1) id - user id of the user
2) name - user name
朋友表列
1) user_id
2) friend_id
问题:
我希望逐个从USERS表中获取用户,并为不是朋友的用户批量插入FRIENDS表。
我知道我可以通过JOIN逐一检查并做一些事情。但我不认为这是一种简单而正确的做法。需要专家对此的一些看法。
注意: user_id和friend_id中的值可以互换,但仍然意味着他们是朋友。不应该有像(1,2)和(2,1)这样的组合。
SQL小提琴: http://sqlfiddle.com/#!2/07b2d9/1
对于提供的小提琴,所有用户必须成为其他用户的朋友,而忽略已经是朋友的用户。
答案 0 :(得分:1)
这应该可以解决问题:
insert into friends (user_id, friend_id)
select a.id as user_id,
b.id as friend_id
-- Join users to itself. The join constraint results in all of the combinations of
-- two friend IDs, rather than all of the permutations.
from users a
inner join users b on a.id < b.id
-- Remove rows from the results that have a matching row in the friends table.
where not exists (
select f.user_id
from friends f
where ((f.user_id = a.id and f.friend_id = b.id) or
(f.user_id = b.id and f.friend_id = a.id))
);
答案 1 :(得分:1)
识别不是&#34;朋友&#34;的所有用户组合。与其他用户一起假设您只需要一行(例如(1,4)
)来代表:friendship:而不是两行(例如(1.4)
,(4,1)
)
SELECT u.id AS user_id
, t.id AS friend_id
FROM users u
JOIN users t
ON t.id > u.id
LEFT
JOIN friends f
ON f.user_id = u.id
AND f.friend_id = t.id
LEFT
JOIN friends g
ON g.user_id = t.id
AND g.friend_id = u.id
WHERE f.user_id IS NULL
AND g.user_id IS NULL
此查询之前可以有INSERT INTO friends (user_id, friend_id)
将这些行插入到friends表中。
users表与其自身的连接会获得所有组合,但我们希望排除user_id
和friend_id
具有相同值的行;我们只想要关系的一面,所以我们可以排除user_id&gt;的行。 friend_id。
要排除friends表中已存在的行,我们可以使用反连接模式。因为我们只想要两个可能的行(1,4)或(4,1)中的一个,并且其中任何一个可能已经存在,我们都会进行两种检查。
要为单个用户执行此操作,请添加:
AND ( u.id = 4 OR t.id = 4 )