我有以下表格:
user
+-----------------------------------------------+
| user_id | username | Password | ... |
+-----------------------------------------------+
| 1 | a | *** | ... |
+-----------------------------------------------+
| 2 | b | *** | ... |
+-----------------------------------------------+
| 3 | c | *** | ... |
+-----------------------------------------------+
| 4 | d | *** | ... |
+-----------------------------------------------+
| 5 | e | *** | ... |
+-----------------------------------------------+
friends
+-----------------------------------------------+
| f_id | user_id | friend_id | ... |
+-----------------------------------------------+
| 1 | 4 | 2 | ... |
+-----------------------------------------------+
| 2 | 4 | 1 | ... |
+-----------------------------------------------+
| 3 | 4 | 5 | ... |
+-----------------------------------------------+
| 4 | 4 | 3 | ... |
+-----------------------------------------------+
我希望将所有可用的用户添加为好友(在这种情况下,user_id
1
将有3个好友添加(2, 3, 5)
。但是,使用以下SQL statement below
我只能添加1个用户(4)
:
$sql = "SELECT * FROM user WHERE user.user_id NOT IN
(SELECT friends.friend_id FROM friends) AND
user.user_id <> $_SESSION['id']." ORDER BY RAND() LIMIT 5";
但是当我以用户4登录时没有可用的用户可用,这种方法很有效。这对我来说有点棘手。任何想法都会非常感激。
由于
答案 0 :(得分:2)
这个怎么样? null
显示用户4
不应将用户4
添加为朋友的位置。实际上,您可以按And FID is not null
过滤掉它。如果您希望根据select to be added friends
session id
特定用户,那么您也可以在另一个条件下对其进行指定:)
更新了添加其他联接,以确保为朋友显示名称,而不是为其他用户显示。除此之外不再存在4
。
查询:
select x.id, a.name, x.fid
from users a
join (
select u.id, u.name, f.fid
from users u
left join friends f
on u.id <> f.fid
and u.id <> f.uid) x
on x.fid = a.id
;
结果:
| ID | NAME | FID |
-------------------
| 1 | b | 2 |
| 1 | e | 5 |
| 1 | c | 3 |
| 2 | a | 1 |
| 2 | e | 5 |
| 2 | c | 3 |
| 3 | b | 2 |
| 3 | a | 1 |
| 3 | e | 5 |
| 5 | b | 2 |
| 5 | a | 1 |
| 5 | c | 3 |
对于特定用户,例如1
select x.id, x.fid, a.name
from users a
join
(select u.id, f.fid
from users u
inner join friends f
on u.id <> f.fid
and u.id <> f.uid
and u.id = 1)x
on x.fid = a.id
;
| ID | FID | NAME |
-------------------
| 1 | 2 | b |
| 1 | 3 | c |
| 1 | 5 | e |
答案 1 :(得分:1)
您的SQL查询正在做的是:获取id不等于任何friend_id的所有用户,而不是当前用户(我假设)。
你想要的是检查朋友表中的friend_id和user_id对没有记录,如下所示:$ sql =
"SELECT * FROM user WHERE user.user_id NOT IN
(SELECT friends.friend_id FROM friends WHERE friend.user_id = user.user_id) AND
user.user_id <> $_SESSION['id']." ORDER BY RAND() LIMIT 5";
答案 2 :(得分:1)
您可以尝试NOT IN
JOIN
表,而不是将friends
与子查询一起使用。
我JOIN
两次编辑。一旦1
为user_id
,1
为friend_id
。1
为1
。然后,我收到的所有用户都不是SELECT user.user_id,user.username
FROM user
LEFT JOIN friends AS fA ON fA.user_id = 1
LEFT JOIN friends AS fB ON fB.friend_id = 1
WHERE user.user_id != 1
AND NOT (user.user_id <=> fB.user_id)
AND NOT (user.user_id <=> fA.friend_id)
或{{1}}的朋友。
{{1}}
答案 3 :(得分:1)
编辑:
这个怎么样: (in else子句使用无效的id或与登录用户相同的id)
select * from users where id not in
(
select (
case
when uid = 1 then id
when fid = 1 then uid
else 0
end
) from friends where uid = 1 or fid = 1
) and id != 1 order by rand() limit 5;
http://sqlfiddle.com/#!2/12de1/62
解决此问题的另一种方法(但可能不是最佳解决方案):
如果用户拥有的朋友数量少于系统中的用户总数,则下面的联合查询可能不是一个代价高昂的查询,而不是两个表之间的完全联接。
另请不要忘记在uid
表的fid
和friends
列添加索引。
select * from users where id not in
(
select id from friends where uid = 1
union
select uid from friends where fid = 1
) and id != 1 order by rand() limit 5;
答案 4 :(得分:0)
您在子查询中缺少where子句,以将其限制为您要排除的当前用户朋友。
$sql = "select * from user u
where u.user_id not in
(select f.friend_id from friends f where f.user_id = ".$_SESSION['id'].")
and u.user_id <> ".$_SESSION['id']." ORDER BY RAND() LIMIT 5";
我还建议不要使用字符串连接来执行此操作。 PDO会更安全,你不会有SQL注入的风险。
答案 5 :(得分:0)
SELECT u1.id u1_id
, u2.id u2_id
FROM users u1
JOIN users u2
ON u2.id <> u1.id
LEFT
JOIN friends f
ON (f.fid = u1.id AND f.uid = u2.id)
OR (f.fid = u2.id AND f.uid = u1.id)
WHERE f.id IS NULL;