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?

Kevin
fonte

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.

Mark Byers
fonte
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).

paxdiablo
fonte
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.

Gianpaolo Papa
fonte
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.

ackuser
fonte
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;
Krishna_K_Systematix
fonte