Aviso: o valor nulo é eliminado por uma agregação ou outra operação SET no Aqua Data Studio

95

Tenho um problema quando os dados são nulos e o aviso aparece quando o resultado é exibido. Como resolver este problema?. Como alterar os dados nulos para 0 quando não há dados na tabela ?.

Este é o meu código: -

SELECT DISTINCT c.username             AS assigner_officer,
                d.description          AS ticketcategory,
                (SELECT Count(closed)
                 FROM   ticket
                 WHERE  assigned_to = c.user_id
                        AND closed IS NOT NULL
                 GROUP  BY assigned_to)closedcases,
                (SELECT Count(closed)
                 FROM   ticket
                 WHERE  assigned_to = c.user_id
                        AND closed IS NULL
                 GROUP  BY assigned_to)opencases
FROM   ticket a
       JOIN ticketlog b
         ON a.ticketid = b.ticketid
       JOIN access c
         ON a.assigned_to = c.user_id
       JOIN ticket_category d
         ON a.cat_code = d.id
       JOIN lookup_department e
         ON a.department_code = e.code 

O resultado aparece assim: -

 Warnings: ---> 
   W (1): Warning: Null value is eliminated by an aggregate or other SET operation.
          <--- 
 assigner_officer     ticketcategory     closedcases     opencases    
 -------------------  -----------------  --------------  ------------ 
 abdulhafiz           Enquiry            (null)          0            
 affan                Enquiry            12              (null)       
 amirul               Enquiry            1               (null)       
 azrul_fahmi          Enquiry            45              0            
 Azwani               Enquiry            (null)          0            
 chai                 Enquiry            4               (null)       
 dalinawati           Enquiry            1               0            
 Emmy                 Complaints         (null)          0            
 Fadhlia              Enquiry            38              0            
 fairulhalif          Others             1               (null)       
 farikh               Enquiry            (null)          0            
 ismailh              Enquiry            28              0            
 izzahanna            Enquiry            (null)          0            
 Kamsuzilawati        Enquiry            1               (null)     
Amin SCO
fonte
1
Count(closed) ... WHERE ... closed IS NULLnão faz nenhum sentido, pois COUNTapenas conta NOT NULLvalores
Martin Smith
1
Possível duplicata do Aviso
trenó
Estou recebendo o mesmo aviso. Não me importo com o aviso em si, mas preciso que o procedimento armazenado seja executado pelo SQL Agent e, quando faço isso, o aviso causa uma falha no trabalho do agente.
RichieACC
Esta pergunta não faz sentido.
xr280xr

Respostas:

101

Você usaria principalmente COUNTpara resumir em um UID. Portanto

COUNT([uid]) irá produzir o aviso:

Aviso: o valor nulo é eliminado por uma agregação ou outra operação SET.

enquanto estiver sendo usado com uma junção à esquerda, onde o objeto contado não existe.

COUNT(*)Nesse caso, usar também renderizaria resultados incorretos, pois você contaria o número total de resultados (ou seja, pais) que existem.

Usar COUNT([uid])É uma forma válida de contagem e o aviso nada mais é do que um aviso. No entanto, se você estiver preocupado e quiser obter uma contagem real de uids neste caso, poderá usar:

SUM(CASE WHEN [uid] IS NULL THEN 0 ELSE 1 END) AS [new_count]

Isso não aumentaria muito a sua consulta. (testado mssql 2008)

Mat Traherne
fonte
1
Eu pesquisei e tentei sem sucesso, mas usar NULLIF em conjunto com ISNULL me salvou. Você pode tentar a combinação dos dois, por exemplo: ISNULL (NULLIF ([fieldValue], 0), 1)
QMaster
A solução especificamente para a coluna "opencases" não seria mais simples do que apenas "select count (1) ..." (ou "count" de qualquer outro literal)? A cláusula Where já especifica "e fechado é NULL", portanto, não há necessidade de somar uma instrução case nesta instância. Além disso, ouvi (eras atrás) que "contar (*)" não é tão eficiente quanto contar uma única coluna ou literal, mas não tenho certeza se esse ainda é o caso.
RowanPD
Em vez de count([uid]), funcionaria para usar count(1)?
Farhan de
O senhor @Mat Traherne me salvou :) Peguei esta tentando conectar dados em um arquivo Excel, já tinha um ISNULL (x, y) mas não funcionou, porém "SUM (CASO QUANDO X É NULO ENTÃO 0 ELSE X END) AS Z "funcionou muito bem! Obrigado!
Dimitri
19

Uma maneira de resolver esse problema é desativando os avisos.

SET ANSI_WARNINGS OFF;
GO
Mukus
fonte
30
A partir do msdn , isso não apenas altera os avisos sobre nulos em agregados, mas também modifica o tratamento de divisão por zero e erros de estouro. Isso faz com que essa solução seja um "não vai" para mim.
Frédéric
3
Por que você considera isso um problema? é apenas informativo
Martin Smith
2
@Mukus - Não, não faz. Ele imprime uma mensagem no nível de Severidade 10. Qualquer coisa 10 ou inferior é informativa não é considerada um erro. SELECT SUM(X) FROM (VALUES ( 1 + NULL)) V(X);SELECT 'This is executed fine';
Martin Smith
5
@RichieACC Sim, porque isso não é uma resposta, e desabilitar os avisos ANSI extremamente desejáveis ​​como uma forma preguiçosa de evitar uma mensagem informativa causará a quebra de muitas outras coisas distintamente não informativas.
underscore_d
3
A solução para as luzes de advertência do seu carro é simplesmente desligar o painel. Esta é provavelmente a pior resposta que já vi no stackoverflow.
VoronoiPotato
17

Use ISNULL(field, 0)Também pode ser usado com agregados:

ISNULL(count(field), 0)

No entanto, você pode considerar mudar count(field) to count(*)

Editar:

experimentar:

closedcases = ISNULL(
   (select count(closed) from ticket       
    where assigned_to = c.user_id and closed is not null       
    group by assigned_to), 0), 

opencases = ISNULL(
    (select count(closed) from ticket 
     where assigned_to = c.user_id and closed is null 
     group by assigned_to), 0),
Chris Gessler
fonte
Eu tentei, mas o (nulo) ainda existe na linha. Como alterar esse valor para 0 quando os dados são nulos?
Amin SCO
obrigado, mas o valor não nulo também teve o mesmo problema quando o valor nulo é exibido. como alterar o valor para 0 ?.
Amin SCO
1
Para sua informação: ISNULL(count(field), 0)não funcionou para mim no MSSQL 2008 R2. O problema era porque eu estava tentando contar um campo em uma tabela unida externa esquerda para obter o número de registros na tabela unida relacionada à tabela principal. Acabei tendo que fazer uma subconsulta que unia internamente as duas tabelas para obter a contagem por ID na tabela principal. A subconsulta foi deixada externamente associada à tabela principal no ID. A contagem da subconsulta foi então agrupada em um ISNULL para obter o 0 que eu queria (sem a mensagem de aviso).
Trisped
1
Chris, deve ser COUNT (ISNULL (Field, 0)) e não o contrário. Consultando o formato atual, tudo o que será retornado é um 0 e não uma contagem real. Lógica: Count (campo) retornará um único NULL para todos os valores de campo que são nulos e ISNULL definirá isso como 0, retornando 0.
Govind Rai
9

Você deseja colocar o ISNULLinterior da COUNTfunção, não o exterior:

Não é bom: ISNULL(COUNT(field), 0)

BOA: COUNT(ISNULL(field, 0))

Ben Garrison
fonte
12
Isto está errado. count(ISNULL(field, 0))será equivalente a count(*), pois o valor que está sendo contado não pode mais ser NULL.
@hvd não está errado, o valor é apenas 0 quando o campo é nulo.
Govind Rai
3
@GovindRai Não, realmente está errado. Se você acredita que pode inventar um contra-exemplo, um exemplo em que COUNT(ISNULL(field, 0))é diferente COUNT(*), faça-o. O SQL Fiddle torna mais fácil compartilhar esse contra-exemplo. Mas você não será capaz. Como COUNTconta os valores não nulos, mesmo que sejam zero, e ISNULL(field, 0)sempre é um valor não nulo, COUNT(ISNULL(field, 0))conta as linhas. É para isso que COUNT(*)serve e não para o que o OP aqui estava atrás.
2
@hvd Você está correto. Minha resposta foi baseada em uma group byconsulta em um contexto diferente daquele que o OP buscava. No meu caso, ISNULL(COUNT(field), 0)retornaria uma contagem de 0 para todos os valores NULL, o que estava incorreto, pois havia vários valores nulos, ao passo COUNT(ISNULL(field),0)que retornaria a contagem correta para o número total de valores NULL. Mas, novamente, dois cenários totalmente diferentes.
Govind Rai
Tenho que trabalhar. Aqui está! sqlfiddle.com/#!3/ee0546/2 votou em seu comentário lol
Govind Rai
-2

Eu estava recebendo este erro; Acabei de colocar uma WHEREcláusula para o campo que foi usado na countcláusula. resolveu o problema. Nota: se existir valor nulo, verifique se é crítico para o relatório, pois está excluído da contagem.

Consulta antiga:

select city, Count(Emp_ID) as Emp_Count 
from Emp_DB
group by city

Nova consulta:

select city, Count(Emp_ID) as Emp_Count 
from Emp_DB
where Emp_ID is not null
group by city
Hariishr
fonte
-3

Se houver qualquer valor Nulo dentro da função agregada, você enfrentará esse problema. Em vez do código abaixo

 SELECT Count(closed)
  FROM   ticket
  WHERE  assigned_to = c.user_id
  AND closed IS NULL

usar como

SELECT Count(ISNULL(closed, 0))
  FROM   ticket
  WHERE  assigned_to = c.user_id
  AND closed IS NULL
Maniv
fonte