Проблема, с которой вы столкнулись, возникает из-за того, что результат SUBSTR
равен нулю, если нет пробела.И благодаря логике трех значений результат some_var <> NULL
равен NULL, а не TRUE, как вы могли ожидать.
И пример этого показан в следующем запросе:
with mytab as (
select 1 as myval from dual union all
select 2 as myval from dual union all
select null as myval from dual
)
select *
from mytab
where myval = 1
union all
select *
from mytab
where myval <> 1
Этот пример вернет только две строки, а не три строки, которые вы могли бы ожидать.
Есть несколько способов переписать условие, чтобы оно игнорировало нулевой результат функции substr.Они перечислены ниже.Однако, как упомянул один из других респондентов, эти два условия необходимо объединить с помощью оператора AND, а не OR.
Во-первых, вы можете явно проверить, что в столбце есть пробел, используя наборУсловия ниже:
(INSTR(company,' ') = 0 or
UPPER(SUBSTR(company, 0, (INSTR(company,' ')-1))) <> 'CABS') and
COMPANY <> 'CABS'
Другой вариант - использовать функцию LNNVL
.Это функция, о которой я узнал совсем недавно.Он возвращает TRUE из условия, когда результатом условия, предоставленного в качестве входного значения, является FALSE или NULL.
lnnvl(UPPER(SUBSTR(company, 0, (INSTR(company,' ')-1))) = 'CABS') and
COMPANY <> 'CABS'
И еще один вариант (который, вероятно, был бы моим предпочтительным вариантом) - использовать функцию REGEXP_LIKE
,Это просто, по сути и легко читается.
WHERE not regexp_like(company, '^CABS( |$)')