LEFT JOIN和WHERE结果中包含NULL值

时间:2017-12-06 15:37:08

标签: mysql sql join left-join

一个简单的查询为我提供了user1与其他用户的关系:

select u.id, u.name, ur.*
from users u
left join user_relationships ur
on ((ur.source_user_id = 1 and target_user_id = u.id) OR
    (ur.source_user_id = u.id and target_user_id = 1))
where u.id != 1
ORDER BY u.id; 

+----+-------+----------+--------+------+
| id | name  | rel_from | rel_to | type |
+----+-------+----------+--------+------+
|  2 | beta  | 2        | 1      | 2    |
|  3 | gamma | 1        | 3      | 2    |
|  4 | delta | 4        | 1      | 1    |
|  5 | five  | NULL     | NULL   | NULL |
+----+-------+----------+--------+------+

但我只想要一个与type不是2('delta'和'five')的用户列表。

我尝试了一些方法。

-- Approach 1
-- -----------------------------
    where 
    (u.id != 1) AND
    (ur.type != 2)
    -- gives 'delta', not 'five'


-- Approach 2
-- -----------------------------    
left join user_relationships ur
on ((ur.source_user_id = 1 and target_user_id = u.id) OR
    (ur.source_user_id = u.id and target_user_id = 1)) AND 
    (ur.type != 2)
where 
    (u.id != 1)    
ORDER BY u.id;
-- ur.* fields are NULL
-- (all rows, except for 'delta')


-- Approach 3
-- -----------------------------    
where 
    (u.id != 1) AND
    ((ur.type != 2) OR 
    (ur.type IS NULL))
    -- this works, but why ?

(A)为什么方法1,2不起作用,但3不起作用?

(B)是否有其他(也许更优雅)的方法可以达到相同的效果?

1 个答案:

答案 0 :(得分:2)

卡亚,

使用可能的空值时,应使用IS NULL比较。

所以你的位置可能是:

 where 
    (u.id != 1) AND
    (ur.type != 2 OR ur.type IS NULL)