Devuelve 0 si el campo es nulo en MySQL

160

En MySQL, ¿hay alguna forma de establecer los campos "totales" en cero si son NULL?

Esto es lo que tengo:

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;

Los datos salen bien, excepto que los campos NULL deberían serlo 0.

¿Cómo puedo devolver 0 para NULL en MySQL?

Kevin
fuente

Respuestas:

327

Use IFNULL :

IFNULL(expr1, 0)

De la documentación:

Si expr1 no es NULL, IFNULL () devuelve expr1; de lo contrario, devuelve expr2. IFNULL () devuelve un valor numérico o de cadena, según el contexto en el que se usa.

Mark Byers
fuente
¿Sería 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: No, el alias va al final.
Mark Byers
2
@ MarkByers, ¿puede mostrar por qué el ejemplo de Kevin en el comentario es incorrecto y cuál debería ser realmente?
Michael
Muchas gracias !! Esto es exactamente lo que estaba buscando
brunobliss
@MarkByers IFNOtNULL (expr1, 1) ¿hay algo así?
Noni
25

Puedes usar en coalesce(column_name,0)lugar de solo column_name. La coalescefunción devuelve el primer valor no NULL de la lista.

Debo mencionar que las funciones por fila como esta suelen ser problemáticas para la escalabilidad. Si cree que su base de datos puede llegar a tener un tamaño decente, a menudo es mejor usar columnas y disparadores adicionales para mover el costo del selectal insert/update.

Esto amortiza el costo asumiendo que su base de datos se lee con más frecuencia que se escribe (y la mayoría de ellos lo hacen).

paxdiablo
fuente
Esto sucede una vez por semana para facturar a todos los clientes. Los datos se escriben toda la semana, luego, en un momento determinado, se calculan y facturan. Piense en ello como un servicio de suscripción. Puede realizar cambios durante la vigencia del período de facturación, y su actividad se cobra a intervalos apropiados.
Kevin
Agregaría que en esta situación preferiría la fusión porque es la misma sintaxis para MS y My SQL, mientras que MS SQL es iSnull y MySQL es iFnull, si eso es importante para alguien. (MySQL ISNULL es una función diferente que ISNULL de MS SQL)
Craig Jacobs
11

Ninguna de las respuestas anteriores fue completa para mí. Si se nombra su campo field, entonces el selector debería ser el siguiente:

IFNULL(`field`,0) AS field

Por ejemplo en una consulta SELECT:

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

Espero que esto pueda ayudar a alguien a no perder el tiempo.

Gianpaolo Papa
fuente
5

Puedes probar algo como esto

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

Se supone que el atributo X está vacío si se trata de una cadena vacía, por lo que después de eso puede declarar como cero en lugar del último valor. En otro caso, seguiría siendo su valor original.

De todos modos, solo para dar otra forma de hacerlo.

ackuser
fuente
Esto funcionó para mí genial en medio de un SELECT vs el IFNULL normal (var, 0)
ajankuv
5

Sí, la función IFNULL funcionará para lograr el resultado deseado.

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;
Krishna_K_Systematix
fuente