Estou tentando descobrir uma consulta fácil que posso fazer para testar se uma tabela grande possui uma lista de entradas que possui pelo menos UM valor em branco (NULL/vazio) em QUALQUER coluna.
Eu preciso de algo como
SELECT * FROM table AS t WHERE ANY(t.* IS NULL)
eu não quero ter que fazer
SELECT * FROM table AS t WHERE t.c1 = NULL OR t.c2 = NULL OR t.c3 = NULL
Esta seria uma consulta ENORME.
Uma extensão para a resposta do @ db2 com menos (leia-se: zero) hand-wrangling:
Você deve listar todas as colunas conforme o comentário de JNK.
Uma abordagem um pouco menos eficiente que evita isso está abaixo.
(Com base nesta resposta SO)
Não há uma boa sintaxe integrada, mas o Management Studio tem alguns recursos convenientes para gerar a consulta rapidamente.
No Pesquisador de Objetos, desça até a tabela desejada, expanda-a e arraste toda a pasta "Colunas" para um editor de consulta em branco. Isso adicionará uma lista de colunas separadas por vírgulas à consulta.
Em seguida, abra Localizar e substituir. Defina "Localizar o que" para
,
e defina "Substituir por" paraIS NULL OR
(com um espaço à esquerda) e pressione Substituir tudo. Você terá que limpar o último da sequência manualmente.Ainda é feio, mas é menos trabalhoso e feio.
Várias soluções para: alguns nulos, todos os nulos, colunas únicas e múltiplas, além de torná-lo RÁPIDO usando o Top 1
Se você precisar testar várias colunas, poderá usar o seguinte:
Primeiro , teste para NULLs e conte-os:
Produz uma contagem de NULLs:
Onde o resultado é 0, não há NULLs.
Segundo , vamos contar os não-NULLs:
...Mas como estamos contando não-NULLs aqui, isso pode ser simplificado para:
Qualquer um rende:
Onde o resultado é 0, a coluna é inteiramente composta de NULLs.
Por fim , se você só precisa verificar uma coluna específica, o TOP 1 é mais rápido porque deve parar no primeiro hit. Você pode então opcionalmente usar count(*) para dar um resultado no estilo booleano:
0 = Não há NULLs, 1 = Há pelo menos um NULL
ou
0 = Todos são NULL, 1 = Existe pelo menos um não NULL
Eu espero que isso ajude.
UNPIVOT converte colunas em linhas. No processo elimina valores NULL ( referência ).
Dada a entrada
a consulta UNPIVOT
produzirá a saída
Infelizmente, a linha 4 foi totalmente eliminada, pois possui apenas NULLs! Ele pode ser convenientemente reintroduzido injetando um valor fictício na consulta de origem:
Ao agregar as linhas no ID, podemos contar os valores não nulos. Uma comparação com o número total de colunas na tabela de origem identificará as linhas que contêm um ou mais NULL.
Eu calculo 3 como
número de colunas na tabela de origem #t
+ 1 para a coluna fictícia injetada
- 1 para ID, que não é UNPIVOTED
Esse valor pode ser obtido em tempo de execução examinando as tabelas do catálogo.
As linhas originais podem ser recuperadas juntando-se aos resultados.
Se valores diferentes de NULL devem ser investigados, eles podem ser incluídos em uma cláusula where:
Discussão
Isso requer um identificador que é transportado pelo UNPIVOT. Uma chave seria melhor. Se não existir, um pode ser injetado pela função de janela ROW_NUMBER() , embora isso possa ser caro para executar.
Todas as colunas devem ser explicitamente listadas dentro da cláusula UNPIVOT. Eles podem ser arrastados usando o SSMS, como sugerido pelo @db2. Não será dinâmico quando a definição da tabela mudar, como seria a sugestão de Aaron Bertrand. Este é o caso de quase todos os SQL, no entanto.
Para meu conjunto de dados bastante limitado, o plano de execução é uma varredura de índice clusterizado e uma agregação de fluxo. Isso custará mais memória do que uma varredura direta da tabela e muitas cláusulas OR.