这个使用NOT IN的简单查询出了什么问题?

时间:2009-12-03 14:08:47

标签: sql postgresql

架构:

radio_bin.id
radio.id
radio.radio_bin -> radio_bin.id

查询:

select *
    from radio_bin

72行。

select *
    from radio_bin
    where id in (select radio_bin from radio)

50行。

(和FWIW:)

select distinct radio_bin
    from radio

51行,包括null。

这一切都很好。现在:

select *
    from radio_bin
    where id not in (select radio_bin from radio)

0行。

为什么呢?我不应该得到没有收音机指向他们的22个radio_bin.id号码吗?

5 个答案:

答案 0 :(得分:6)

试试这个,你有一个空值,null不等于任何其他空值

select *
    from radio_bin
    where id not in (select radio_bin from radio where radio_bin  is not null)

另请参阅NOT IN and NULLS,其中介绍了如何使用LEFT JOIN或NOT EXISTS

答案 1 :(得分:2)

更改

in

Exists

这有用吗?

点击此处查看explanation

答案 2 :(得分:2)

radio_bin.id null是否可能?

如果是NOT IN does not evaluate to true

这是因为x NOT IN y相当于NOT (x IN y)。如果xnull,那么(x IN y)将返回null,因为没有任何内容等于null,甚至不等于null

答案 3 :(得分:1)

因为NULL确实很糟糕。以下是在Oracle上运行但我认为这种行为是标准的ANSI SQL行为......

SQL> select * from t23
  2  where id in ( select id from t42)
  3  /

TXT                                                ID
------------------------------------------ ----------
SAM-I-AM                                            1
KNOX                                                2
FOX                                                 3

SQL> select * from t23
  2  where id not in ( select id from t42)
  3  /

no rows selected

SQL> update t42 set id = 8 where id is null
  2  /

1 row updated.

SQL> select * from t23
  2  where id not in ( select id from t42)
  3  /

TXT                                                ID
------------------------------------------ ----------
LORAX                                               9

SQL>

答案 4 :(得分:1)

如果您计划大幅度扩大此查询,请避免使用NOT IN。如果你在谈论一个小应用程序它不应该是一个问题,但如果你正在谈论数百万行(甚至可能)避免这种方法!

  

负面操作,例如<>或不   喜欢,也很难   有效地解决。尝试重写   如果可以,他们会用另一种方式。如果你   只检查存在,使用   IF EXISTS或IF NOT EXISTS   而是构建。你可以使用   指数。如果使用扫描,则可以停止   第一次出现的扫描。   http://msdn.microsoft.com/en-us/library/ms998577.aspx