Retorne 0 se o campo for nulo no MySQL


160

No MySQL, existe uma maneira de definir os campos "total" para zero se forem NULL?

Aqui está o que eu tenho:

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;

Os dados são bons, exceto que os campos NULL devem ser 0.

Como posso retornar 0 para NULL no MySQL?

Respostas:


326

Use IFNULL :

IFNULL(expr1, 0)

A partir da documentação:

Se expr1 não for NULL, IFNULL () retornará expr1; caso contrário, ele retornará expr2. IFNULL () retorna um valor numérico ou de seqüência de caracteres, dependendo do contexto em que é usado.


Isso seria IFNULL ((SELECT SUM (uop.price * uop.qty) FROM uc_order_products uop WHERE uo.order_id = uop.order_id) AS products_subtotal, 0)?
22410 Kevin

2
@ Kevin: Não - o apelido continua no final.
Mark Byers

2
@ MarkByers, você pode mostrar por que o exemplo de Kevin no comentário está errado e qual deveria ser?
Michael

muito obrigado !! Este é exatamente o que eu estava procurando
brunobliss

@MarkByers IFNOtNULL (expr1, 1) não há nada parecido
Noni

25

Você pode usar em coalesce(column_name,0)vez de apenas column_name. A coalescefunção retorna o primeiro valor não NULL da lista.

Devo mencionar que funções por linha como essa geralmente são problemáticas para escalabilidade. Se você acha que seu banco de dados pode ter um tamanho decente, geralmente é melhor usar colunas e gatilhos extras para mover o custo de selectpara o insert/update.

Isso amortiza o custo, pressupondo que seu banco de dados seja lido com mais frequência do que escrito (e a maioria deles).


Isso acontece uma vez por semana para cobrar todos os clientes. Os dados são gravados durante toda a semana e, em um determinado momento, são computados e cobrados. Pense nisso como um serviço de assinatura. Você pode fazer alterações durante o período de cobrança e sua atividade é cobrada em intervalos apropriados.
22710 Kevin

Eu acrescentaria que, nessa situação, eu preferiria coalescer porque é a mesma sintaxe para MS e My SQLs, enquanto MS SQL é iSnull e MySQL é iFnull, se isso for importante para alguém. (MySQLs ISNULL é uma função diferente que ISNULL MS SQL)
Craig Jacobs

11

Nenhuma das respostas acima foi completa para mim. Se o seu campo for nomeado field, o seletor deverá ser o seguinte:

IFNULL(`field`,0) AS field

Por exemplo, em uma consulta SELECT:

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

Espero que isso ajude alguém a não perder tempo.


5

Você pode tentar algo assim

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

Presume-se que o atributo X esteja vazio se for uma String vazia; portanto, você poderá declarar como zero em vez de último valor. Em outro caso, permaneceria seu valor original.

Enfim, apenas para dar outra maneira de fazer isso.


Isso funcionou para mim grande no meio de um SELECT vs o IFNULL normal (var, 0)
ajankuv

5

Sim A função IFNULL estará trabalhando para alcançar o resultado desejado.

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;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.