我不确定我是否在逻辑上犯了错误。
如果我有一个查询,并且我使用空值进行内连接,那么我总是得不到结果,还是会忽略连接并成功?示例
user { id PK, name NVARCHAR NOT NULL, banStatus nullable reference }
如果我写和u.banStatus我将不会收到任何行?
select * from user as u
join banstatus as b on u.banStatus=b.id
where id=1
答案 0 :(得分:48)
如果连接为null,则不会获取该行,因为NULL不能等于任何内容,即使是NULL。
如果您将其更改为LEFT JOIN,那么您将获得该行。
使用内部联接:
select * from user as u
join banstatus as b on u.banStatus=b.id
1, '1', 1, 'Banned'
使用左连接:
select * from user as u
left join banstatus as b on u.banStatus=b.id
1, '1', 1, 'Banned'
2, 'NULL', , ''
使用此测试数据:
CREATE TABLE user (id int, banstatus nvarchar(100));
INSERT INTO user (id, banstatus) VALUES
(1, '1'),
(2, 'NULL');
CREATE TABLE banstatus (id int, text nvarchar(100));
INSERT INTO banstatus (id, text) VALUES
(1, 'Banned');
答案 1 :(得分:7)
当您执行INNER JOIN
时,NULL
值与任何内容都不匹配。甚至没有彼此。这就是为什么您的查询不返回任何行。 (Source)
答案 2 :(得分:5)
这是nulls的内连接(Oracle语法):
select *
from user
uu
join banstatus
bb
on uu.banstatus = bb.id
or
uu.banstatus is null and bb.id is null
答案 3 :(得分:2)
空值不等于任何其他值,因此连接条件对于空值不成立。您可以通过选择其他联接条件来获得所需的结果。代替
u.banStatus = b.id
使用
u.banStatus = b.id OR (u.banStatus IS NULL AND b.id IS NULL)
对于这种比较,某些SQL方言具有更简洁的语法:
-- PostgreSQL
u.banStatus IS NOT DISTINCT FROM b.id
-- SQLite
u.banStatus IS b.id