Трюк в Oracle с использованием выражений или функций:
Если это все числовые значения c, вы можете просто использовать +
:
with t(a, b, c) as (
select 1, 2, 3 from dual union all
select null, 2, 3 from dual union all
select null, null, 3 from dual
)
select *
from t
where a + b + c is null;
Это дает
A|B|C|
-|-|-|
|2|3|
| |3|
Также можно использовать менее читаемую функцию DECODE
, или GREATEST
, как Гари уже показал :
decode(null, a, 1, b, 1, c, 1, 0) = 1;
Использование MINUS
Вы можете использовать (a, b, c) = ((a, b, c))
, чтобы проверить, является ли ни одно из значений NULL
, в случае чего предикат дает NULL
. К сожалению, поскольку Oracle не знает BOOLEAN
типов, вы не можете NULL
проверять сам предикат (и LNNVL
, похоже, не работает с вышеуказанным условием), но вы можете использовать MINUS
:
with t(a, b, c) as (
select 1, 2, 3 from dual union all
select null, 2, 3 from dual union all
select null, null, 3 from dual
)
select *
from t
minus
select *
from t
where (a, b, c) = ((a, b, c)); -- None of the values is NULL
Во многих случаях это, очевидно, медленное решение, поэтому не очень хорошее.
Стандарт SQL:
Стоит отметить, что стандарт SQL (например, реализован на PostgreSQL, но не Oracle) поддерживает нулевые предикаты для выражений значения строки, например:
not ((a, b, c) is not null)
"Двойной отрицательный" необходим, поскольку таблица истинности показывает, что not x is null
и x is not null
это не одно и то же ( источник ):
+-----------------------+-----------+---------------+---------------+-------------------+
| Expression | R IS NULL | R IS NOT NULL | NOT R IS NULL | NOT R IS NOT NULL |
+-----------------------+-----------+---------------+---------------+-------------------+
| degree 1: null | true | false | false | true |
| degree 1: not null | false | true | true | false |
| degree > 1: all null | true | false | false | true |
| degree > 1: some null | false | false | true | true |
| degree > 1: none null | false | true | true | false |
+-----------------------+-----------+---------------+---------------+-------------------+