123 votes

Avertissement : Une valeur nulle est éliminée par un agrégat ou une autre opération SET dans Aqua Data Studio.

J'ai un problème lorsque les données sont nulles et que l'avertissement apparaît lorsque le résultat est affiché. Comment résoudre ce problème ? Comment changer la donnée nulle en 0 lorsqu'il n'y a pas de données dans le tableau ?

Voici mon code :-

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 

Le résultat ressemble à ceci:-

 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)

2 votes

Count(closed) ... WHERE ... closed IS NULL n'a pas de sens comme COUNT ne compte que NOT NULL valeurs

0 votes

Je reçois le même avertissement. L'avertissement ne me dérange pas en soi, mais j'ai besoin que la procédure stockée soit exécutée par l'agent SQL, et lorsque je fais cela, l'avertissement fait échouer la tâche de l'agent.

122voto

Mat Traherne Points 256

Vous utiliserez principalement COUNT à résumer sur un UID. Par conséquent,

COUNT([uid]) produira l'avertissement :

Avertissement : La valeur nulle est éliminée par un agrégat ou une autre opération SET.

tout en étant utilisé avec une jointure gauche, où l'objet compté n'existe pas.

Utilisation de COUNT(*) dans ce cas, les résultats seraient également incorrects, car vous compteriez alors le nombre total de résultats (c'est-à-dire de parents) qui existent.

Utilisation de COUNT([uid]) C'est une façon valide de compter, et l'avertissement n'est rien de plus qu'un avertissement. Cependant, si vous êtes concerné, et que vous voulez obtenir un vrai compte d'uids dans ce cas, vous pouvez utiliser :

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

Cela n'ajouterait pas beaucoup de frais généraux à votre requête. (testé mssql 2008)

1 votes

J'ai cherché et essayé sans succès mais l'utilisation de NULLIF en conjonction avec ISNULL m'a sauvé. Vous pouvez essayer de combiner ces deux éléments par exemple : ISNULL(NULLIF([fieldValue], 0), 1)

0 votes

La solution spécifique à la colonne "opencases" ne serait-elle pas plus simple comme "select count(1)...". (ou "count" de tout autre littéral) ? La clause Where spécifie déjà "and closed is NULL", il n'est donc pas nécessaire d'additionner une déclaration de cas dans ce cas. De plus, j'ai entendu dire (il y a des lustres) que "count(*)" n'est pas aussi efficace que le comptage d'une seule colonne ou d'un seul littéral, mais je ne sais pas si c'est toujours le cas.

0 votes

Au lieu de count([uid]) Est-ce que ça marcherait d'utiliser count(1) ?

31voto

Mukus Points 1104

Une façon de résoudre ce problème est de désactiver les avertissements.

SET ANSI_WARNINGS OFF;
GO

41 votes

De msdn Cela ne change pas seulement les avertissements concernant les nullités dans les agrégats, mais modifie également le traitement des erreurs de division par zéro et de débordement. Cette solution est donc à proscrire pour moi.

3 votes

Pourquoi le considérez-vous comme un problème de toute façon ? il s'agit juste d'une information

2 votes

@Mukus - Non, il ne le fait pas. Il imprime un message au niveau de sévérité 10. Tout ce qui est 10 ou moins est informatif et n'est pas considéré comme une erreur. SELECT SUM(X) FROM (VALUES ( 1 + NULL)) V(X);SELECT 'This is executed fine';

16voto

Chris Gessler Points 11887

Utilisez ISNULL(field, 0) Il peut également être utilisé avec des agrégats :

ISNULL(count(field), 0)

Cependant, vous pourriez envisager de changer count(field) to count(*)

Edit :

essayez :

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),

0 votes

J'ai essayé mais le (null) existe toujours dans la ligne. Comment changer cette valeur en 0 lorsque les données sont nulles ?

0 votes

merci mais la valeur non nulle a aussi le même problème lorsque la valeur nulle apparaît. comment changer la valeur en 0 ?

1 votes

FYI : ISNULL(count(field), 0) n'a pas fonctionné pour moi dans MSSQL 2008 R2. Le problème était que j'essayais de compter un champ dans une table jointe externe à gauche pour obtenir le nombre d'enregistrements de la table jointe liés à la table principale. J'ai fini par faire une sous-requête qui a joint intérieurement les deux tables pour obtenir le compte par ID dans la table principale. La sous-requête a été jointe en externe à la table principale sur l'ID. Le compte de la sous-requête a ensuite été enveloppé dans un ISNULL pour obtenir le 0 que je voulais (sans le message d'avertissement).

16voto

Ben Garrison Points 1

Vous voulez mettre le ISNULL à l'intérieur de la COUNT fonction, pas à l'extérieur :

Pas BON : ISNULL(COUNT(field), 0)

BIEN : COUNT(ISNULL(field, 0))

16 votes

C'est faux. count(ISNULL(field, 0)) sera équivalent à count(*) car la valeur qui est comptée ne peut plus jamais être NULL .

0 votes

@hvd ce n'est pas faux, la valeur est seulement 0 quand le champ est nul.

6 votes

@GovindRai Non, c'est vraiment mal. Si vous pensez que vous pouvez trouver un contre-exemple, un exemple où COUNT(ISNULL(field, 0)) est différent de COUNT(*) veuillez le faire, Fiddle SQL permet de partager facilement un tel contre-exemple. Mais vous ne pourrez pas le faire. Puisque COUNT compte les valeurs non nulles même si elles sont nulles, et ISNULL(field, 0) est toujours une valeur non nulle, COUNT(ISNULL(field, 0)) compte les rangs. C'est ce que COUNT(*) et non ce que recherchait le PO ici.

-1voto

Sabri Points 74

Si vous avez aussi quelque chose comme ça, vous recevrez un avertissement,

.
.
HAVING ISNULL( SUM(ci.CommissionAmount - ci.PaidAmount),0) >0

Ça doit être comme ça,

.
.
SUM(ISNULL(ci.CommissionAmount,0) - ISNULL(ci.PaidAmount,0)) >0

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X