Por que um nulo não pode ser igual a um nulo por causa de uma junção?
Apenas diga à Oracle para fazer isso:
select *
from one t1
join two t2 on coalesce(t1.id, -1) = coalesce(t2.id, -1);
(Observe que no SQL padrão você pode usar t1.id is not distinct from t2.id
para obter um operador de igualdade com segurança nula, mas o Oracle não suporta isso)
Mas isso só funcionará se o valor de substituição (-1 no exemplo acima) não aparecer realmente na tabela. Encontrar um valor "mágico" para números pode ser possível, mas será muito difícil para os valores dos caracteres (especialmente porque o Oracle também trata uma string vazia null
)
Mais: nenhum índice nas id
colunas será usado (você pode definir um índice baseado em função com a coalesce()
expressão).
Outra opção que funciona para todos os tipos, sem valores mágicos:
on t1.id = t2.id or (t1.id is null and t2.id is null)
Mas a verdadeira questão é: isso faz sentido?
Considere os seguintes dados de exemplo:
Quadro um
id
----
1
2
(null)
(null)
Quadro dois
id
----
1
2
(null)
(null)
(null)
Qual combinação de valores nulos deve ser escolhida na junção? Meu exemplo acima resultará em algo como uma junção cruzada para todos os valores nulos.
T1_ID | T2_ID
-------+-------
1 | 1
2 | 2
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
where (a = b or (a is null and b is null))
final. são os meus pensamentos sobre isso. Eu não consideraria usarsys_op_map_nonnull
, ignoraria aquele homem atrás da cortina. "Você pode associar valores nulos usando decodificação:
decode
trata nulos como iguais, portanto, isso funciona sem números "mágicos". As duas colunas devem ter o mesmo tipo de dados.Não criará o código mais legível, mas provavelmente ainda melhor do que
t1.id = t2.id or (t1.id is null and t2.id is null)
fonte
Por que você não pode usar valores nulos em junções? No Oracle, os seguintes itens não são avaliados como verdadeiros:
NULL = NULL
NULL <> NULL
É por isso que temos
IS NULL
/IS NOT NULL
para verificar valores nulos.Para testar isso, você pode simplesmente fazer:
As junções estão avaliando uma condição booleana e não as programaram para operar de maneira diferente. Você pode colocar um sinal de maior que na condição de junção e adicionar outras condições; apenas avalia como uma expressão booleana.
Eu acho que um nulo não pode ser igual a um nulo em junções por uma questão de consistência. Isso desafiaria o comportamento usual do operador de comparação.
fonte
NULL = anything
resultaNULL
porque o padrão SQL diz isso. Uma linha satisfaz a condição de junção apenas se a expressão for verdadeira.Um valor nulo na maioria dos bancos de dados relacionais é considerado DESCONHECIDO. Não deve ser confundido com todos os zeros HEX. se algo contiver nulo (desconhecido), você não poderá compará-lo.
O que significa que, sempre que você tiver um nulo como operando em uma expressão booleana, a parte else será sempre verdadeira.
Ao contrário do ódio geral contra o nulo pelos desenvolvedores, o nulo tem seu lugar. Se algo for desconhecido, use null.
fonte
UNKNOWN
, nãoFALSE
;)