¿Por qué un nulo no puede ser igual a un nulo por el bien de una unión?
Solo dile a Oracle que haga eso:
select *
from one t1
join two t2 on coalesce(t1.id, -1) = coalesce(t2.id, -1);
(Tenga en cuenta que en SQL estándar podría usar t1.id is not distinct from t2.id
para obtener un operador de igualdad nulo-seguro, pero Oracle no lo admite)
Pero esto solo funcionará si el valor de reemplazo (-1 en el ejemplo anterior) en realidad no aparece en la tabla. Puede ser posible encontrar un valor "mágico" para los números , pero será muy difícil para los valores de los caracteres (especialmente porque Oracle también trata una cadena vacía null
)
Además: no id
se utilizará ningún índice en las columnas ( aunque podría definir un índice basado en funciones con la coalesce()
expresión).
Otra opción que funciona para todos los tipos, sin valores mágicos:
on t1.id = t2.id or (t1.id is null and t2.id is null)
Pero la verdadera pregunta es: ¿tiene sentido?
Considere los siguientes datos de muestra:
Tabla uno
id
----
1
2
(null)
(null)
Tabla dos
id
----
1
2
(null)
(null)
(null)
¿Cuál de la combinación de valores nulos se debe elegir en la unión? El ejemplo anterior dará como resultado una unión cruzada para todos los valores nulos.
T1_ID | T2_ID
-------+-------
1 | 1
2 | 2
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
un caballo sin nombre
fuente
where (a = b or (a is null and b is null))
punto. Ese es mi pensamiento al respecto. No consideraría usarlosys_op_map_nonnull
, ignorar a ese hombre detrás de la cortina ".Puede unir valores nulos con decodificación:
decode
trata los nulos como iguales, por lo que esto funciona sin números "mágicos". Las dos columnas deben tener el mismo tipo de datos.No hará el código más legible, pero probablemente aún mejor que
t1.id = t2.id or (t1.id is null and t2.id is null)
fuente
¿Por qué no puedes usar valores nulos en uniones? En Oracle, los dos siguientes no se evalúan como verdaderos:
NULL = NULL
NULL <> NULL
Es por eso que tenemos
IS NULL
/IS NOT NULL
para comprobar si hay valores nulos.Para probar esto, simplemente puede hacer:
Las uniones están evaluando una condición booleana, y no las programaron para operar de manera diferente. Puede poner un signo mayor que en la condición de unión y agregar otras condiciones; solo lo evalúa como una expresión booleana.
Supongo que un nulo no puede ser igual a un nulo en uniones por razones de consistencia. Desafiaría el comportamiento habitual del operador de comparación.
fuente
NULL = anything
resultaNULL
porque el estándar SQL lo dice. Una fila satisface la condición de unión solo si la expresión es verdadera.Un valor nulo en la mayoría de las bases de datos relacionales se considera DESCONOCIDO. No debe confundirse con todos los ceros HEX. si algo contiene nulo (desconocido), no puede compararlo.
Lo que significa que siempre que tenga un nulo como operando en una expresión booleana, la parte else siempre será verdadera.
Al contrario del odio general hacia nulo por parte de los desarrolladores, nulo tiene su lugar. Si algo es desconocido, use nulo.
fuente
UNKNOWN
, noFALSE
;)