内部联接空值

时间:2010-01-23 11:41:55

标签: sql mysql tsql sqlite

我不确定我是否在逻辑上犯了错误。

如果我有一个查询,并且我使用空值进行内连接,那么我总是得不到结果,还是会忽略连接并成功?示例

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

4 个答案:

答案 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