Renvoie 0 si le champ est nul dans MySQL


160

Dans MySQL, existe-t-il un moyen de définir les champs "total" à zéro s'ils sont NULL?

Voici ce que j'ai:

SELECT uo.order_id, uo.order_total, uo.order_status,
            (SELECT SUM(uop.price * uop.qty) 
             FROM uc_order_products uop 
             WHERE uo.order_id = uop.order_id
            ) AS products_subtotal,
            (SELECT SUM(upr.amount) 
             FROM uc_payment_receipts upr 
             WHERE uo.order_id = upr.order_id
            ) AS payment_received,
            (SELECT SUM(uoli.amount) 
             FROM uc_order_line_items uoli 
             WHERE uo.order_id = uoli.order_id
            ) AS line_item_subtotal
            FROM uc_orders uo
            WHERE uo.order_status NOT IN ("future", "canceled")
            AND uo.uid = 4172;

Les données sortent correctement, sauf que les champs NULL devraient l'être 0.

Comment puis-je retourner 0 pour NULL dans MySQL?

Réponses:


327

Utilisez IFNULL :

IFNULL(expr1, 0)

De la documentation:

Si expr1 n'est pas NULL, IFNULL () renvoie expr1; sinon, il renvoie expr2. IFNULL () renvoie une valeur numérique ou chaîne, selon le contexte dans lequel elle est utilisée.


Serait-ce IFNULL ((SELECT SUM (uop.price * uop.qty) FROM uc_order_products uop WHERE uo.order_id = uop.order_id) AS products_subtotal, 0)?
Kevin

2
@Kevin: Non - l'alias va à la fin.
Mark Byers

2
@MarkByers pouvez-vous montrer pourquoi l'exemple de Kevin dans le commentaire est faux et ce qu'il devrait réellement être?
Michael

Merci beaucoup !! C'est exactement ce que je cherchais
brunobliss

@MarkByers IFNOtNULL (expr1, 1) y a-t-il quelque chose comme ça
Noni

25

Vous pouvez utiliser coalesce(column_name,0)au lieu de simplement column_name. La coalescefonction renvoie la première valeur non NULL de la liste.

Je dois mentionner que les fonctions par ligne comme celle-ci sont généralement problématiques pour l'évolutivité. Si vous pensez que votre base de données peut arriver à être une taille décente, il est souvent préférable d'utiliser des colonnes et des déclencheurs supplémentaires pour déplacer le coût de l' selectau insert/update.

Cela amortit le coût en supposant que votre base de données est lue plus souvent qu'écrite (et la plupart le sont).


Cela se produit une fois par semaine pour facturer tous les clients. Les données sont écrites toute la semaine, puis à un certain moment, elles sont calculées et facturées. Pensez-y comme un service d'abonnement. Vous pouvez apporter des modifications pendant la durée de la période de facturation et votre activité est facturée à des intervalles appropriés.
Kevin

J'ajouterais que dans cette situation, je préférerais coalesce parce que c'est la même syntaxe pour MS et My SQL, alors que MS SQL est iSnull et MySQL est iFnull, si cela compte pour quelqu'un. (MySQLs ISNULL est une fonction différente de ISNULL de MS SQL)
Craig Jacobs

11

Aucune des réponses ci-dessus n'était complète pour moi. Si votre champ est nommé field, le sélecteur doit être le suivant:

IFNULL(`field`,0) AS field

Par exemple dans une requête SELECT:

SELECT IFNULL(`field`,0) AS field, `otherfield` FROM `mytable`

J'espère que cela peut aider quelqu'un à ne pas perdre de temps.


5

Vous pouvez essayer quelque chose comme ça

IFNULL(NULLIF(X, '' ), 0)

L'attribut X est supposé vide s'il s'agit d'une chaîne vide, vous pouvez donc le déclarer comme un zéro au lieu de la dernière valeur. Dans un autre cas, il resterait sa valeur d'origine.

Quoi qu'il en soit, juste pour donner une autre façon de faire cela.


Cela a très bien fonctionné pour moi au milieu d'un SELECT vs l'IFNULL normal (var, 0)
ajankuv

5

Oui, la fonction IFNULL fonctionnera pour atteindre le résultat souhaité.

SELECT uo.order_id, uo.order_total, uo.order_status,
        (SELECT IFNULL(SUM(uop.price * uop.qty),0) 
         FROM uc_order_products uop 
         WHERE uo.order_id = uop.order_id
        ) AS products_subtotal,
        (SELECT IFNULL(SUM(upr.amount),0) 
         FROM uc_payment_receipts upr 
         WHERE uo.order_id = upr.order_id
        ) AS payment_received,
        (SELECT IFNULL(SUM(uoli.amount),0) 
         FROM uc_order_line_items uoli 
         WHERE uo.order_id = uoli.order_id
        ) AS line_item_subtotal
        FROM uc_orders uo
        WHERE uo.order_status NOT IN ("future", "canceled")
        AND uo.uid = 4172;
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.