oracle 使用WHERE子句时SQL查询结果不相加

eanckbw9  于 2023-03-01  发布在  Oracle
关注(0)|答案(3)|浏览(238)

是什么原因导致我的第二个SQL查询返回的数量少于预期?我有一个包含1000个条目的地址表,在筛选“纽约”城市和“Mainstreet”街道时,我的第一个查询返回100。第二个查询应返回900,但实际上没有。以下是我的查询:

select count(*)
from address_data
where city = 'New York' and street = 'Mainstreet'

select count(*)
from address_data
where not (city = 'New York' and street = 'Mainstreet')
2g32fytz

2g32fytz1#

--  S a m p l e   d a t a :
WITH
    tbl (ID, CITY, STREET) AS 
        (
            Select 1, 'New York', 'Main Street' From Dual Union All
            Select 2, 'New York', 'NOT Main Street' From Dual Union All
            Select 3, 'NOT New York', 'Main Street' From Dual Union All
            Select 4, 'New York', Null From Dual 
        )

-- Your 2nd query returns 2 instead of 3 as count
Select Count(*) "CNT"
From tbl
Where CITY = 'New York' and STREET = 'Main Street'

-- Options for your 2nd query that all return 3 as count

-- Posssible Null values replaced with '-' for comparison
-- using NOT (condition 1 And condition 2)
Select Count(*) "CNT"
From tbl
Where Not (Nvl(CITY, '-') = 'New York' And Nvl(STREET, '-') = 'Main Street')

-- Posssible Null values replaced with '-' for comparison
-- using negative Condition 1 OR negative Condition 2
Select Count(*) "CNT"
From tbl
Where Nvl(CITY, '-') != 'New York' OR Nvl(STREET, '-') != 'Main Street'

-- using negative Condition 1 OR negative Condition 2
-- additional testing for null values separately
Select Count(*) "CNT"
From tbl
Where CITY != 'New York' OR CITY Is Null OR STREET != 'Main Street' OR STREET Is Null
cyvaqqii

cyvaqqii2#

来自文档:
条件指定一个或多个表达式和逻辑(布尔)运算符的组合,并返回值TRUEFALSEUNKNOWN
在关于NULL s的部分中,您可以找到以下说明:
要测试空值,请仅使用比较条件IS NULLIS NOT NULL如果将任何其他条件与空值一起使用,并且结果取决于空值,则结果为UNKNOWN。因为空值表示缺少数据,所以空值不能等于或不等于任何值或其他空值。但是,在计算DECODE函数时,Oracle认为两个空值相等。
只要where子句只返回condition计算结果为TRUE的行(因此它拒绝FALSEUNKNOWN),NOT (<condition>)就不会为您提供具有UNKNOWN条件值的行。
考虑以下示例数据:

create table sample_tab(col) as
  select 'True' from dual union all
  select 'False' from dual union all
  select null from dual

您可以使用LNNVL函数来捕获所有非TRUE的内容:

select *
from sample_tab
where lnnvl(col = 'True')

或者使用纯集方法并使用EXCEPT(Oracle pre-19c中为MINUS)集运算符计算集补:

select *
from sample_tab

except

select *
from sample_tab
where col = 'True'

在这两种情况下,您将得到相同的结果:
| 颜色|
| - ------|
| 假|
| * 无效 *|
fiddle

olqngx59

olqngx593#

我认为城市和街道列中的空值在你的第二个查询中没有被识别出来,所以你可以尝试一下下面的第二个查询;参见:

select count(*)
from address_data
where (NVL(city, '') != 'New York' OR NVL(street, '') != 'Mainstreet'))

相关问题