SQL查询未返回预期结果-省略了Null值

时间:2018-08-22 13:20:28

标签: sql oracle

我尝试以一种简单的方式过滤数据:

SELECT * FROM INFO_CA
WHERE DATE_FACT > TO_DATE('20160101', 'YYYYMMDD')
AND ACCOUNT_SOC <> 'BELGIUM'

此查询返回111926条记录。

  • 过滤日期后,我的表INFO_CA中有10457262条记录。
  • 在ACCOUNT_SOC列中有296条带有'BELGIUM'的记录
  • ACCOUNT_SOC中有111926条记录与比利时不同的记录
  • 在ACCOUNT_SOC中有10 345 040为空值。

如果我使用第二个查询,我将得到预期的结果(10 456 966条记录= 10 345 040 null + 111 926,其中包含比利时以外的其他内容)

SELECT * FROM INFO_CA
WHERE DATE_FACT > TO_DATE('20160101', 'YYYYMMDD')
AND (ACCOUNT_SOC <> 'BELGIUM' OR ACCOUNT_SOC IS NULL)

我正在使用Oracle 12(SQL Developer)+ Talend。即使在Talend中,我的第一个查询也不会返回空值。

那为什么呢?为什么我的第一个查询只返回值与比利时不同或为null的记录。为什么我必须指定我想要ACCOUNT_SOC为空的记录?

ACCOUNT_SOC的数据类型为VARCHAR2(255 BYTE)。

谢谢:)

2 个答案:

答案 0 :(得分:2)

NULL means that the value is not known. Therefore a value that is null in the ACCOUNT_SOC field will not qualify under the condition ACCOUNT_SOC <> 'BELGIUM' because the in the case of NULLS the ACCOUNT_SOC is not known. It isn't BELGIUM and it isn't NOT BELGIUM - its not known.

In summary NULLS can be tricky so your best bet is to do a little research so you know what effects they can have.

You could also do

NVL(ACCOUNT_SOC,'XXX') <> 'BELGIUM'

Which will convert a NULL value to 'XXX' which you can then reliably check

答案 1 :(得分:0)

使用NOT EXISTS的替代方法 在处理带有NOTS的NULL时有一个棘手的问题,通过将NOT EXISTS与键列的JOIN一起使用,结果将为NULL。

SELECT * FROM INFO_CA a
WHERE NOT EXISTS (SELECT 1 FROM  INFO_CA b WHERE /*join of key columns*/ a.PK_col=b.PKcol AND b.ACCOUNT_SOC = 'BELGIUM' )
AND a.DATE_FACT > TO_DATE('20160101', 'YYYYMMDD')