Por que quando temos um valor NULL em uma coluna e ordenamos pelo valor crescente, os NULLs são classificados primeiro?
select 1 as test
union all
select 2
union all
select NULL
union all
select 3
union all
select 4
order by test
resulta em
NULL
1
2
3
4
Eu continuo pensando que NULL significava "Indeterminado" ou possível "Desconhecido". Se isso é verdade, eles não classificariam por último, já que o valor poderia ser maior que todos os outros valores? (Ou essa é uma opção de classificação em algum lugar?)
Estou no SQL Server 2008R2, mas suspeito que isso seja verdade em todos os servidores SQL e provavelmente em todos os RDBMSs.
sql-server
database-theory
sorting
Richard
fonte
fonte
desc
ordem para mostrar as coisas maiores ou mais recentes; nesse caso, eu ficaria feliz que as coisas nulas fossem as últimas.Respostas:
NULL significa desconhecido. Nenhuma outra interpretação é válida.
Não pode haver . Não há valor potencial . Desconhecido é desconhecido é desconhecido.
Quanto ao motivo pelo qual aparece primeiro, e não por último, isso não é atendido pelos padrões SQL publicados e infelizmente é deixado a critério do fornecedor do RDBMS:
fonte
Você está certo que
NULL
pode significar 'Indeterminado' ou 'Desconhecido' ou 'Ainda não conhecido' ou 'Não se aplica'. Mas não há razão para colocar os nulos em primeiro ou último. Se não soubermos os valores reais, eles podem ser pequenos ou grandes.Eu acho que o padrão para determinar o comportamento desejado dos Nulos durante a classificação é:
Infelizmente, o SQL-Server ainda não adotou esta sintaxe. Se não estou errado, o PostgreSQL e a Oracle têm.
Uma solução:
Outra solução que precisa de ajuste, dependendo do tipo de dados - mas não será executada corretamente, pois não pode usar um índice em
(test)
:fonte
Não sei por que isso foi feito dessa maneira, mas, por definição, NULLS não pode ser comparado a não NULLS, então eles precisam ir no início ou no final (a resposta de Mark cobre isso com muito mais detalhes).
Para obter o comportamento que você deseja - Até onde eu sei, não há opção de classificação para colocar os nulos por último, então você deve evitá-lo usando uma coluna computada para forçá-los a durar. No entanto, no SQL Server, você não pode solicitar por uma coluna computada (
CASE WHEN ...
) quando seus dados contiverem um operador definido (UNION ALL
). Tão:Funcionará para classificar os nulos por último. Se você precisar usar
UNION
(ouEXCEPT
ouINTERSECTS
) para gerar seu conjunto de dados, despeje-os em uma tabela temporária como acima.fonte
Se você está lidando com números, também pode usar
NULL
são os valores mais baixos possíveis, portanto osDESC
coloca no final. Enquanto isso, os valores não nulos têm o sinal invertido, entãoDESC
na verdade é umASC
dos valores reais. Isso deve ser mais rápidoCASE
e suponho que o otimizador de consulta também possa usar índices natest
coluna.fonte
(- test)
.