Ostrzeżenie: Wartość zerowa jest eliminowana przez agregację lub inną operację SET w Aqua Data Studio

97

Mam problem, gdy dane są zerowe i pojawia się ostrzeżenie, gdy wynik jest wyświetlany. Jak rozwiązać ten problem? Jak zmienić puste dane na 0, gdy nie ma danych w tabeli?

To jest mój kod: -

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 

Wynik wygląda następująco: -

 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
źródło
1
Count(closed) ... WHERE ... closed IS NULLnie ma sensu, ponieważ COUNTliczy tylko NOT NULLwartości
Martin Smith
Otrzymuję to samo ostrzeżenie. Nie przeszkadza mi samo ostrzeżenie, ale potrzebuję, aby procedura składowana była uruchamiana przez agenta SQL, a kiedy to robię, ostrzeżenie powoduje niepowodzenie zadania agenta.
RichieACC
To pytanie nie ma sensu.
xr280xr

Odpowiedzi:

104

Używałbyś głównie COUNTdo podsumowania przez UID. W związku z tym

COUNT([uid]) wyświetli ostrzeżenie:

Ostrzeżenie: wartość zerowa jest eliminowana przez agregację lub inną operację SET.

podczas używania z lewym złączeniem, gdy liczony obiekt nie istnieje.

Użycie COUNT(*)w tym przypadku również spowoduje wyświetlenie niepoprawnych wyników, ponieważ wtedy zliczasz całkowitą liczbę wyników (tj. Rodziców), które istnieją.

Używanie COUNT([uid])IS jest prawidłowym sposobem liczenia, a ostrzeżenie to nic innego jak ostrzeżenie. Jeśli jednak jesteś zaniepokojony i chcesz uzyskać w tym przypadku prawdziwą liczbę uidów, możesz użyć:

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

Nie spowodowałoby to dużego obciążenia zapytania. (przetestowano mssql 2008)

Mat Traherne
źródło
1
Szukałem i próbowałem bez powodzenia, ale użycie NULLIF w połączeniu z ISNULL uratowało mnie, możesz spróbować kombinacji tych dwóch, na przykład: ISNULL (NULLIF ([fieldValue], 0), 1)
QMaster
Czy rozwiązanie specjalnie dla kolumny „opencases” nie byłoby prostsze, tak jak po prostu „select count (1) ...” (lub „count” dowolnego innego literału)? Klauzula Where już określa „i zamknięte ma wartość NULL”, więc w tym przypadku nie ma potrzeby sumowania instrukcji case. Słyszałem również (eony temu), że "count (*)" nie jest tak wydajne jak zliczanie pojedynczej kolumny lub literału, ale nie jestem pewien, czy nadal tak jest.
RowanPD
Czy zamiast count([uid])tego zadziała count(1)?
Farhan
Pan @Mat Traherne mnie uratował :) Mam to próbując połączyć dane w pliku Excela, miałem już ISNULL (x, y), ale to nie zadziałało, jednak "SUMA (CASE WHEN X IS NULL THEN 0 ELSE X END) AS Z "działało świetnie! Dzięki!
Dimitri
21

Jednym ze sposobów rozwiązania tego problemu jest wyłączenie ostrzeżeń.

SET ANSI_WARNINGS OFF;
GO
Mukus
źródło
32
W msdn nie tylko zmienia to ostrzeżenia o wartości zerowej w agregatach, ale także modyfikuje obsługę błędów dzielenia przez zero i przepełnienia. To powoduje, że to rozwiązanie jest dla mnie „nie do przyjęcia”.
Frédéric
3
Dlaczego w ogóle uważasz to za problem? to tylko informacja
Martin Smith
2
@Mukus - Nie, nie ma. Wyświetla komunikat z poziomem ważności 10. Cokolwiek 10 lub niższego jest informacją, a nie błędem. SELECT SUM(X) FROM (VALUES ( 1 + NULL)) V(X);SELECT 'This is executed fine';
Martin Smith
5
@RichieACC Tak, ponieważ to nie jest odpowiedź, a wyłączenie niezwykle pożądanych ostrzeżeń ANSI jako leniwego sposobu na uniknięcie jednego komunikatu informacyjnego spowoduje uszkodzenie wielu innych, wyraźnie nieinformacyjnych rzeczy.
underscore_d
3
Rozwiązaniem problemu zapalonych świateł ostrzegawczych w samochodzie jest po prostu odłączenie deski rozdzielczej. To prawdopodobnie najgorsza odpowiedź, jaką kiedykolwiek widziałem w przypadku przepełnienia stosu.
VoronoiPotato
18

Zastosowanie ISNULL(field, 0)Może być również używany z agregatami:

ISNULL(count(field), 0)

Możesz jednak rozważyć zmianę count(field) to count(*)

Edytować:

próbować:

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
źródło
Próbowałem, ale (null) nadal istnieje w rzędzie. Jak zmienić tę wartość na 0, gdy dane są zerowe?
Amin SCO,
dziękuję, ale wartość nie null również ma ten sam problem, gdy pojawia się wartość null. jak zmienić wartość na 0 ?.
Amin SCO,
1
FYI: ISNULL(count(field), 0)nie działa dla mnie w MSSQL 2008 R2. Problem polegał na tym, że próbowałem policzyć pole w lewej zewnętrznej tabeli połączonej, aby uzyskać liczbę rekordów w tabeli połączonej związanej z tabelą główną. Skończyło się na tym, że musiałem wykonać zapytanie podrzędne, które połączyło się wewnętrznie z dwiema tabelami, aby uzyskać liczbę według identyfikatora w głównej tabeli. Zapytanie podrzędne pozostawiono zewnętrznie połączone z główną tabelą na identyfikatorze. Liczba zapytania podrzędnego została następnie opakowana w ISNULL, aby uzyskać 0, które chciałem (bez komunikatu ostrzegawczego).
Trisped
1
Chris, to powinno być COUNT (ISNULL (Field, 0)), a nie odwrotnie. Przy zapytaniu o aktualny format, wszystko, co zostanie zwrócone, to 0, a nie rzeczywista liczba. Logika: Count (pole) zwróci pojedynczą wartość NULL dla wszystkich wartości pól, które są zerowe, a ISNULL ustawi ją na 0, zwracając 0.
Govind Rai
10

Chcesz umieścić ISNULLwnętrzeCOUNT funkcji, a nie na zewnątrz:

Niedobrze: ISNULL(COUNT(field), 0)

DOBRY: COUNT(ISNULL(field, 0))

Ben Garrison
źródło
12
To jest źle. count(ISNULL(field, 0))będzie równoważne count(*), ponieważ liczona wartość nie może już być NULL.
@hvd to nie jest źle, wartość wynosi tylko 0, gdy pole jest puste.
Govind Rai
3
@GovindRai Nie, to naprawdę jest złe. Jeśli uważasz, że możesz wymyślić kontrprzykład, przykład COUNT(ISNULL(field, 0))różniący się od COUNT(*), zrób to, SQL Fiddle ułatwia udostępnienie takiego kontrprzykładu. Ale nie będziesz w stanie. Ponieważ COUNTzlicza wartości inne niż null, nawet jeśli są one równe zero i ISNULL(field, 0)jest zawsze wartością różną od null, COUNT(ISNULL(field, 0))zlicza wiersze. Po to COUNT(*)jest, a nie po to, aby OP.
2
@hvd Masz rację. Moja odpowiedź była oparta na group byzapytaniu w innym kontekście niż to, czego szukał PO. W moim przypadku ISNULL(COUNT(field), 0)zwróciłoby liczbę 0 dla wszystkich wartości NULL, co było niepoprawne, ponieważ istniało wiele wartości null, podczas gdy COUNT(ISNULL(field),0)zwróciłoby poprawną liczbę dla łącznej liczby wartości NULL. Ale znowu dwa zupełnie różne scenariusze.
Govind Rai
Mam to do pracy. Proszę bardzo! sqlfiddle.com/#!3/ee0546/2 Głosował za twoim komentarzem lol
Govind Rai
-2

Otrzymywałem ten błąd; Po prostu umieściłem WHEREklauzulę dla pola, które zostało użyte w countklauzuli. rozwiązał problem. Uwaga: jeśli istnieje wartość null, sprawdź, czy jest ona krytyczna dla raportu, ponieważ została wykluczona z liczby.

Stare zapytanie:

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

Nowe zapytanie:

select city, Count(Emp_ID) as Emp_Count 
from Emp_DB
where Emp_ID is not null
group by city
hariishr
źródło
-3

Jeśli jakakolwiek wartość Null istnieje wewnątrz funkcji agregującej, napotkasz ten problem. Zamiast poniższego kodu

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

użyj jak

SELECT Count(ISNULL(closed, 0))
  FROM   ticket
  WHERE  assigned_to = c.user_id
  AND closed IS NULL
Maniv
źródło