Comment obtenir la fonction SUM dans MySQL pour renvoyer «0» si aucune valeur n'est trouvée?


150

Disons que j'ai une fonction simple dans MySQL:

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

Si aucune entrée dans Column_2 ne contient le texte 'Test', cette fonction retourne NULL, alors que je voudrais qu'elle renvoie 0.

Je suis conscient qu'une question similaire a été posée à quelques reprises ici, mais je n'ai pas été en mesure d'adapter les réponses à mes objectifs, alors je serais reconnaissant de l'aide pour faire ce tri.


duplication possible de l' aide avec MySQL SUM ()
JohnFx

Réponses:


305

Utilisez COALESCEpour éviter ce résultat.

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

Pour le voir en action, veuillez consulter ce violon SQL: http://www.sqlfiddle.com/#!2/d1542/3/0


Plus d'information:

Étant donné trois tables (une avec tous les nombres, une avec tous les nuls et une avec un mélange):

Violon SQL

Configuration du schéma 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);

Requête 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

Résultats :

| 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
Merci Brad. Cela fait bien le travail.
Nick

1
SELECT SUM (IFNULL (column, 0)) FROM table GROUP BY n'est-il pas quelque chose de plus correct? Et si nous avons des valeurs IS NULL et des valeurs réelles dans la "colonne"?
DarkSide

2
@DarkSide: Absolument rien d' inattendu.
Brad Christie

@BradChristie oui vous avez absolument raison. SUM fonctionne également avec les valeurs NULL.
DarkSide

1
Veuillez noter que while SUMfonctionne comme vous le souhaitez AVGet COUNTpeut produire des résultats différents lors de la réception de l' NULLinvite à utiliser COALESCEcomme suggéré par @DarkSide, en fonction du résultat souhaité.
fyrye

65

Utilisez IFNULLou COALESCE:

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

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

La différence entre eux est qu'il IFNULLs'agit d'une extension MySQL qui prend deux arguments et COALESCEest une fonction SQL standard qui peut prendre un ou plusieurs arguments. Lorsque vous n'avez que deux arguments, l'utilisation IFNULLest légèrement plus rapide, bien qu'ici la différence soit insignifiante car elle n'est appelée qu'une seule fois.


3
@Mark quelle est la différence b / w IFNULLou COALESCE?? pouvez-vous l'expliquer ??
mo sean

1
PS. Pour toute personne travaillant avec Postgres, il prend uniquement en charge coalesce.
Siddhartha

4

Vous ne pouvez pas obtenir exactement ce que vous demandez, mais si vous utilisez une fonction SOMME d'agrégation qui implique que vous regroupez la table.

La requête va pour MYSQL comme ceci

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

Vous groupez par condition mais ne le retournez pas (vous obtiendrez un tas de quantités de conditions inconnues)?
Lluis Martinez
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.