AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 14864
Accepted
Dexter
Dexter
Asked: 2012-03-13 12:14:37 +0800 CST2012-03-13 12:14:37 +0800 CST 2012-03-13 12:14:37 +0800 CST

Teste se alguma coluna é NULL

  • 772

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.

sql-server sql-server-2008
  • 5 5 respostas
  • 132304 Views

5 respostas

  • Voted
  1. Best Answer
    Aaron Bertrand
    2012-03-13T12:45:31+08:002012-03-13T12:45:31+08:00

    Uma extensão para a resposta do @ db2 com menos (leia-se: zero) hand-wrangling:

    DECLARE @tb nvarchar(512) = N'dbo.[table]';
    
    DECLARE @sql nvarchar(max) = N'SELECT * FROM ' + @tb
        + N' WHERE 1 = 0';
    
    SELECT @sql += N' OR ' + QUOTENAME(name) + N' IS NULL'
        FROM sys.columns 
        WHERE [object_id] = OBJECT_ID(@tb)
        AND is_nullable = 1;
    
    EXEC sys.sp_executesql @sql;
    
    • 19
  2. Martin Smith
    2012-03-13T12:26:29+08:002012-03-13T12:26:29+08:00

    Você deve listar todas as colunas conforme o comentário de JNK.

    WHERE c1 IS NULL OR c2 IS NULL OR c3 IS NULL
    

    Uma abordagem um pouco menos eficiente que evita isso está abaixo.

    ;WITH xmlnamespaces('http://www.w3.org/2001/XMLSchema-instance' AS ns) 
    SELECT * 
    FROM   YourTable AS T1 
    WHERE (
        SELECT T1.* 
        FOR XML PATH('row'), ELEMENTS XSINIL, TYPE
      ).exist('//*/@ns:nil') = 1 
    

    (Com base nesta resposta SO)

    • 9
  3. db2
    2012-03-13T12:29:22+08:002012-03-13T12:29:22+08:00

    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" para IS 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.

    • 5
  4. jwolf
    2018-01-18T14:31:34+08:002018-01-18T14:31:34+08:00

    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:

    Column_1 Column_2 Column_3
    -------- -------- --------
    1        2        NULL
    1        NULL     NULL
    5        6        NULL
    

    Primeiro , teste para NULLs e conte-os:

    select 
        sum(case when Column_1 is null then 1 else 0 end) as Column_1, 
        sum(case when Column_2 is null then 1 else 0 end) as Column_2, 
        sum(case when Column_3 is null then 1 else 0 end) as Column_3,
    from TestTable 
    

    Produz uma contagem de NULLs:

    Column_1  Column_2  Column_3
    0         1         3
    

    Onde o resultado é 0, não há NULLs.

    Segundo , vamos contar os não-NULLs:

    select 
        sum(case when Column_1 is null then 0 else 1 end) as Column_1, 
        sum(case when Column_2 is null then 0 else 1 end) as Column_2, 
        sum(case when Column_3 is null then 0 else 1 end) as Column_3,
    from TestTable
    

    ...Mas como estamos contando não-NULLs aqui, isso pode ser simplificado para:

    select 
        count(Column_1) as Column_1, 
        count(Column_2) as Column_2, 
        count(Column_3) as Column_3,
    from TestTable
    

    Qualquer um rende:

    Column_1  Column_2  Column_3
    3         2         0
    

    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:

    select top 1 'There is at least one NULL' from TestTable where Column_3 is NULL
    
    select count(*) from (select top 1 'There is at least one NULL' AS note from TestTable where Column_3 is NULL) a
    

    0 = Não há NULLs, 1 = Há pelo menos um NULL

    ou

    select top 1 'There is at least one non-NULL' AS note from TestTable where Column_3 is not NULL
    
    select count(*) from (select top 1 'There is at least one non-NULL' AS note from TestTable where Column_3 is not NULL) a
    

    0 = Todos são NULL, 1 = Existe pelo menos um não NULL

    Eu espero que isso ajude.

    • 4
  5. Michael Green
    2018-01-18T18:46:19+08:002018-01-18T18:46:19+08:00

    UNPIVOT converte colunas em linhas. No processo elimina valores NULL ( referência ).

    Dada a entrada

    create table #t
    (
        ID  int primary key,
        c1  int null,
        c2  int null
    );
    
    insert #t(id, c1, c2)
    values
        (1, 12, 13),
        (2, null, 14),
        (3, 15, null),
        (4, null, null);
    

    a consulta UNPIVOT

    select
        ID, ColName, ColValue
    from
    (
        select *
        from #t
    ) as p
    unpivot
    (
        ColValue for ColName in
        (c1, c2)                  -- explicit source column names required
    ) as unpvt;
    

    produzirá a saída

    | ID | ColName | ColValue |
    |----|---------|----------|
    | 1  | c1      | 12       |
    | 1  | c2      | 13       |
    | 2  | c2      | 14       |
    | 3  | c1      | 15       |
    

    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:

    select
        ID, ColName, ColValue
    from
    (
        select
            -5 as dummy,               -- injected here, -5 is arbitrary
            *
        from #t
    ) as p
    unpivot
    (
        ColValue for ColName in
        (dummy, c1, c2)                -- referenced here
    ) as unpvt;
    

    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.

    select
        ID
    from
    (
        select -5 as dummy, *
        from #t
    ) as p
    unpivot
    (
        ColValue for ColName in
        (dummy, c1, c2)
    ) as unpvt
    group by ID
    having COUNT(*) <> 3;
    

    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:

    ...
    ) as unpvt
    where ColValue <> ''      -- will eliminate empty strings
    

    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.

    • 2

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Quanto "Padding" coloco em meus índices?

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

  • Como determinar se um Índice é necessário ou necessário

  • Downgrade do SQL Server 2008 para 2005

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve