Jak uzyskać funkcję SUMA w MySQL, aby zwracała „0”, jeśli nie znaleziono żadnych wartości?

150

Powiedzmy, że mam prostą funkcję w MySQL:

SELECT SUM(Column_1)
FROM Table
WHERE Column_2 = 'Test'

Jeśli żadne wpisy w Column_2 nie zawierają tekstu `` Test '', ta funkcja zwraca NULL, podczas gdy chciałbym, aby zwracała 0.

Zdaję sobie sprawę, że podobne pytanie zostało tutaj zadane kilka razy, ale nie byłem w stanie dostosować odpowiedzi do moich celów, więc byłbym wdzięczny za pomoc w rozwiązaniu tego problemu.

Nacięcie
źródło
możliwy duplikat Help with MySQL SUM ()
JohnFx

Odpowiedzi:

305

Użyj, COALESCEaby uniknąć tego wyniku.

SELECT COALESCE(SUM(column),0)
FROM   table
WHERE  ...

Aby zobaczyć to w akcji, zobacz to sql fiddle: http://www.sqlfiddle.com/#!2/d1542/3/0


Więcej informacji:

Biorąc pod uwagę trzy tabele (jedna ze wszystkimi liczbami, jedna ze wszystkimi zerami i jedna z mieszanką):

SQL Fiddle

Konfiguracja schematu MySQL 5.5.32 :

CREATE TABLE foo
(
  id    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  val   INT
);

INSERT INTO foo (val) VALUES
(null),(1),(null),(2),(null),(3),(null),(4),(null),(5),(null),(6),(null);

CREATE TABLE bar
(
  id    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  val   INT
);

INSERT INTO bar (val) VALUES
(1),(2),(3),(4),(5),(6);

CREATE TABLE baz
(
  id    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  val   INT
);

INSERT INTO baz (val) VALUES
(null),(null),(null),(null),(null),(null);

Zapytanie 1 :

SELECT  'foo'                   as table_name,
        'mixed null/non-null'   as description,
        21                      as expected_sum,
        COALESCE(SUM(val), 0)   as actual_sum
FROM    foo
UNION ALL

SELECT  'bar'                   as table_name,
        'all non-null'          as description,
        21                      as expected_sum,
        COALESCE(SUM(val), 0)   as actual_sum
FROM    bar
UNION ALL

SELECT  'baz'                   as table_name,
        'all null'              as description,
        0                       as expected_sum,
        COALESCE(SUM(val), 0)   as actual_sum
FROM    baz

Wyniki :

| TABLE_NAME |         DESCRIPTION | EXPECTED_SUM | ACTUAL_SUM |
|------------|---------------------|--------------|------------|
|        foo | mixed null/non-null |           21 |         21 |
|        bar |        all non-null |           21 |         21 |
|        baz |            all null |            0 |          0 |
Brad Christie
źródło
2
Dzięki, Brad. To ładnie działa.
Nick
1
Czy SELECT SUM (IFNULL (kolumna, 0)) FROM table GROUP BY nie jest bardziej poprawne? A jeśli mamy jakieś wartości IS NULL i niektóre wartości rzeczywiste w „kolumnie”?
DarkSide
2
@DarkSide: Absolutnie nic nieoczekiwanego.
Brad Christie
@BradChristie tak, masz absolutną rację. SUM działa również dobrze z wartościami NULL.
DarkSide
1
Należy pamiętać, że while SUMdziała zgodnie z oczekiwaniami AVGi COUNTmoże dawać różne wyniki, gdy otrzymujesz NULLmonit o użycie COALESCEzgodnie z sugestią @DarkSide, w zależności od pożądanego wyniku.
fyrye
65

Użyj IFNULLlubCOALESCE :

SELECT IFNULL(SUM(Column1), 0) AS total FROM...

SELECT COALESCE(SUM(Column1), 0) AS total FROM...

Różnica między nimi polega na tym, że IFNULLjest to rozszerzenie MySQL, które przyjmuje dwa argumenty i COALESCEjest standardową funkcją SQL, która może przyjmować jeden lub więcej argumentów. Gdy masz tylko dwa argumenty, użycie IFNULLjest nieco szybsze, chociaż tutaj różnica jest nieistotna, ponieważ jest wywoływana tylko raz.

Mark Byers
źródło
3
@ Zaznacz, jaka jest różnica b / w IFNULLczy COALESCE?? czy mógłbyś to wyjaśnić?
mo sean,
1
PS. Dla każdego, kto pracuje z Postgres, obsługuje tylko coalesce.
Siddhartha
4

Nie można uzyskać dokładnie tego, o co pytasz, ale jeśli używasz funkcji zagregowanej SUMA, co oznacza, że ​​grupujesz tabelę.

Zapytanie dotyczy MYSQL w ten sposób

Select IFNULL(SUM(COLUMN1),0) as total from mytable group by condition
Sashi Kant
źródło
Grupujesz według warunku, ale go nie zwracasz (dostaniesz kilka ilości nieznanych warunków)?
Lluis Martinez