表JOIN无法正常运行

时间:2019-01-03 11:27:45

标签: mysql

我有2个表,第一个是users_table,第二个是friends_table

users_table包含有关用户的信息,其中包括banned列,而friends_table是用户之间的友谊。

两个表都具有列user_id,所以我想要的是根据两个表中的条件检索特定用户的朋友数。条件在user_idbanned上。我希望朋友的数量不包括被禁止的用户,但是即使禁止了某个用户朋友,我仍然可以得到朋友的总数。 请帮助我,这是我的查询,这些查询同时运行以检索朋友:

$query1 = "
    SELECT * 
    FROM users_table u 
    INNER JOIN friends_table f ON u.user_id = f.user_id 
    WHERE f.user_id = $user_id AND u.banned = 0
";

$query2 = "
    SELECT * 
    FROM users_table u 
    INNER JOIN friends_table f ON u.user_id = f.friend_id
    WHERE f.friend_id = $user_id AND u.banned = 0
";

修改 “ users_table”结构:

user_id
first_name
last_name
username
email
password
temporarily_banned
banned

“ friends_table”结构:

friendship_id
user_id
friend_id
friendship_timestamp

表格记录示例

users_table示例:

user_id: 20
first_name: Firas
last_name: Helou
username: firashelou
email: mac_987@hotmail.com
password: *******
temporarily_banned: 0
banned: 0

user_id: 30
first_name: Elie
last_name: Helou
username: eliehelou
email: elie@hotmail.com
password: *******
temporarily_banned: 0
banned: 1

user_id: 22
first_name: Jessy
last_name: Helou
username: jessyhelou
email: jessy@hotmail.com
password: *******
temporarily_banned: 0
banned: 1

user_id: 32
first_name: Jad
last_name: Helou
username: jadhelou
email: jad@hotmail.com
password: *******
temporarily_banned: 0
banned: 0

friends_table示例:

friendship_id | user_id | friend_id | friendship_timestamp
10                20         30             1534342490
9                 20         22             1533484062
16                32         20             1541619611

3 个答案:

答案 0 :(得分:2)

JOIN表上需要额外的user,以检查朋友是否被禁止。

您的第一个查询变为:

SELECT * 
FROM users_table u 
INNER JOIN friends_table f ON f.user_id = u.user_id
INNER JOIN users_table uf ON uf.user_id = f.friend_id AND uf.banned = 0
WHERE u.user_id = $user_id

第二个查询:

SELECT * 
FROM users_table u 
INNER JOIN friends_table f ON f.friend_id = u.user_id
INNER JOIN users_table uf ON uf.user_id = f.user_id AND uf.banned = 0
WHERE u.user_id = $user_id 

还可以将两个查询合并为一个,例如:

SELECT * 
FROM users_table u 
LEFT JOIN friends_table f1 ON f1.friend_id = u.user_id
LEFT JOIN users_table uf1 ON uf.user_id = f1.user_id AND uf1.banned = 0
LEFT JOIN friends_table f2 ON f2.user_id = u.user_id
LEFT JOIN users_table uf2 ON uf2.user_id = f2.friend_id AND uf2.banned = 0
WHERE u.user_id = $user_id AND COALESCE(uf1.id, uf2.id) IS NOT NULL

PS:如果您只是在寻找朋友的计数,则可以使用SELECT COUNT(*)代替SELECT *

答案 1 :(得分:1)

您需要两次JOIN个用户表才能确定该朋友是否被禁止。查询1:

SELECT *
FROM users_table u
JOIN friends_table f ON f.user_id = u.user_id
JOIN users_table u2 ON u2.user_id = f.friend_id
WHERE u.user_id = $user_id AND u2.banned = 0

对于您提供的示例数据,这给出了除user_id 32之外没有朋友的预期结果。

查询2:

SELECT *
FROM users_table u
JOIN friends_table f ON f.friend_id = u.user_id
JOIN users_table u2 ON u2.user_id = f.user_id
WHERE u.user_id = $user_id AND u2.banned = 0

对于您提供的示例数据,由于某些被禁止的用户有非被禁止的朋友,因此得出的结果是不同的。

Demo on dbfiddle

答案 2 :(得分:0)

您的查询似乎只是在检查用户本身是否被禁止。 您还需要向用户表中的“朋友”添加另一个联接,以检查其状态:

***假设:friend_table只是一个链接表,没有“禁止”列

SELECT * 
FROM users_table user 
INNER JOIN friends_table f ON u.user_id = f.user_id
INNER JOIN users_table friend on friend.user_id = f.user_id
WHERE f.user_id = $user_id AND 0 NOT IN (u.banned, friend.banned)

SELECT * 
FROM users_table u 
INNER JOIN friends_table f ON u.user_id = f.friend_id
INNER JOIN users_table friend on friend.user_id = f.user_id
WHERE f.friend_id = $user_id AND 0 NOT IN (u.banned, friend.banned)