Sumowanie pól, które mogą mieć wartość NULL

Niedawno odkryłem dość irytujący problem w MySQL. Otóż okazuje się, że nie można sumować wartości NULL z dowolną cyfrą. Wynik takiego zapytania:

SELECT NULL + 5 AS foo;

Zwróci nam wartość NULL. Jak na mój chłopski rozum to powinna być wartość 5. Ten mały problem, może czasami całkiem sprawnie pokrzyżować jakieś zliczania/etc przez co wyniki, które otrzymamy mogą mijać się z rzeczywistością.

Na szczęście udało mi się znaleźć całkiem zgrabne rozwiązanie. Jest nim funkcja COALESCE, która zwraca pierwszą nie-pustą wartość podaną podczas wywołania. Drobna modyfikacja zapytania i mamy poprawny wynik:

SELECT COALESCE(NULL, 0) + 5 AS foo;
Ten wpis umieszczono w kategorii MySQL. Możesz dodać go do zakładek permalink. Dodaj komentarz lub dodaj odpowiedź (trackback): Trackback URL.

7 Komentarze

  1. Weirdo
    Opublikowano 26 September, 2008 at 12:02 | Permalink

    Zasadniczo to MySQL ma rację – powinno być NULL. NULL gdyby miało wartość 0 byłoby zerem, nie null’em.
    NULL oznacza wartość nieokreśloną, nieznaną. Równanie x + 5 = y – mniej więcej tak to nalezy rozumieć.

    Wykorzystanie CASE nie byłoby efektywniejsze?

  2. radmen
    Opublikowano 26 September, 2008 at 08:35 | Permalink

    W sumie to masz rację.
    Co do Case, to wydaje mi się to takim przerostem formy nad treścią :) ew skorzystałbym z IFNULL

  3. Opublikowano 1 October, 2008 at 12:05 | Permalink

    Użytkownikowi nie wyświetlimy “Liczba Twoich punktów: NULL” a o to nie trudno. Ładniej obsłużyć to na poziomie wyciągania danych :) A sama konstrukcja jest ładniejsza niż IF i CASE w mysql. Niestety nie wiem jak z wydajnością? Macie jakieś doświadczenia?

  4. Opublikowano 7 November, 2008 at 12:34 | Permalink

    Tak jak poprzednik, mimo wszystko polecam użyć PHP do zliczania danych. Mysql powinien je tylko wyciągać. A w PHP przecież zawsze można zrobić sobie rzutowanie na (integer) i z NULLa mieć `0`.

  5. zuras
    Opublikowano 17 December, 2008 at 11:00 | Permalink

    to znane zagdanienie relacyjnych baz danych. null to wartosc nieznana ale to nie zero!!! baza danych nie wie co z tym zrobic wiec nie moze dac wyniku jakiegokolwiek dzialania. najprostszym i jednym z najbardziej zalecanych rozwiazan jest unikanie wartosci null poprzez klauzule not null przy definicji kolumny. dlaczego? poniewaz wielu specjalistow uwaza to za jeden z najwiekszych problemow relacyjnych baz danych i jezyka sql ze NULL nie oznacza konkretnego stanu a skoro nie oznacza takowego to lepiej nie dopuscic do wystepowania wartosci null.

    polecam ksiazki Joe Celko ktore zajmuja sie tym i wieloma innymi zaawansowanymi tematami jezyka sql.

  6. Opublikowano 1 February, 2009 at 09:38 | Permalink

    Rafał Piekarski -> Użycie PHP do zliczania danych nie zawsze jest możliwe, jeśli SQL ma posortować wynik zapytania według jakiegoś działania na kilku polach i nie zwraca całej tablicy, tylko wybrany fragment (jest użyty LIMIT). Ja mam właśnie taki przypadek i sumowane pola mogą mieć NULL (musiałem użyć NULL, bo potrzebne mi rozróżnienie na: brak wartości, 0 i >0). Rezygnacja z NULL nie wchodzi więc w grę i wybrałem rozwiązanie z COALESCE.

  7. Lucky
    Opublikowano 13 March, 2009 at 07:23 | Permalink

    A najlepiej już na poziomie projektowania bazy nie dopuścić do wartości NULL. Lepiej ustawić NOT NULL i wartość domyślną, np. 0. Koniec końców – COALESCE jest wydajniejsze niż CASE.

    A NULLa możesz sobie wyobrazić jako czarną dziurę. Nieważne ile tam wrzucisz i tak nie zapełnisz. Zawsze w wyniku będzie NULL. Czy to COUNT, czy SUM, czy konkatenacja, czy działania boolowskie, czy jakiekolwiek inne działanie z wartością nieokreśloną.

Skomentuj

Twój adres email nie zostanie opublikowany i nie będzie rozpowszechniany. Wymagane pola są oznaczone *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>