Come posso ottenere la funzione SUM in MySQL per restituire '0' se non viene trovato alcun valore?


150

Supponiamo che io abbia una semplice funzione in MySQL:

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

Se nessuna voce in Column_2 contiene il testo "Test", questa funzione ritorna NULL, mentre vorrei che restituisse 0.

Sono consapevole che una domanda simile è stata posta alcune volte qui, ma non sono stata in grado di adattare le risposte ai miei scopi, quindi sarei grato per un aiuto per risolvere questo problema.


possibile duplicato di Help with MySQL SUM ()
JohnFx,

Risposte:


305

Utilizzare COALESCEper evitare questo risultato.

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

Per vederlo in azione, vedere questo violino sql: http://www.sqlfiddle.com/#!2/d1542/3/0


Maggiori informazioni:

Dati tre tabelle (una con tutti i numeri, una con tutti i valori null e una con una combinazione):

SQL Fiddle

MySQL 5.5.32 Setup schema :

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

Query 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

Risultati :

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

2
Grazie Brad. Questo fa bene il lavoro.
Nick,

1
SELECT SUM (IFNULL (colonna, 0)) dalla tabella GROUP BY non è qualcosa di più corretto? E se avessimo alcuni valori IS NULL e alcuni valori reali nella "colonna"?
DarkSide,

2
@DarkSide: assolutamente nulla di inaspettato.
Brad Christie,

@BradChristie sì, hai perfettamente ragione. SUM funziona bene anche con valori NULL.
DarkSide,

1
Si prega di essere consapevoli del fatto che while SUMfunziona come desiderato AVGe COUNTpuò produrre risultati diversi quando si riceve la richiesta NULLdi utilizzo COALESCEcome suggerito da @DarkSide, a seconda del risultato desiderato.
Fyrye

65

Usa IFNULLo COALESCE:

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

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

La differenza tra loro è che IFNULLè un'estensione MySQL che accetta due argomenti ed COALESCEè una funzione SQL standard che può accettare uno o più argomenti. Quando hai solo due argomenti usando IFNULLè leggermente più veloce, anche se qui la differenza è insignificante poiché viene chiamata una sola volta.


3
@Mark qual è la differenza in b / n IFNULLo COALESCE?? potresti spiegarlo ??
Mo sean,

1
PS. Per chiunque lavori con Postgres, supporta solo coalesce.
Siddhartha,

4

Impossibile ottenere esattamente quello che stai chiedendo, ma se stai utilizzando una funzione SUM aggregata che implica che stai raggruppando la tabella.

La query vale per MYSQL in questo modo

Select IFNULL(SUM(COLUMN1),0) as total from mytable group by condition

Raggruppi per condizione ma non la restituisci (otterrai un sacco di quantità di condizioni sconosciute)?
Lluis Martinez,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.