Вернуть 0, если поле является пустым в MySQL


160

В MySQL есть ли способ установить «итоговые» поля на ноль, если они равны NULL?

Вот что у меня есть:

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;

Данные получаются нормально, кроме полей NULL 0.

Как я могу вернуть 0 для NULL в MySQL?

Ответы:


327

Используйте IFNULL :

IFNULL(expr1, 0)

Из документации:

Если expr1 не NULL, IFNULL () возвращает expr1; в противном случае он возвращает expr2. IFNULL () возвращает числовое или строковое значение, в зависимости от контекста, в котором оно используется.


Будет ли это IFNULL ((ВЫБЕРИТЕ СУММУ (uop.price * uop.qty) ОТ uc_order_products uop ГДЕ uo.order_id = uop.order_id) AS products_subtotal, 0)?
Кевин

2
@ Кевин: Нет - псевдоним идет в конце.
Марк Байерс

2
@MarkByers: можете ли вы показать, почему пример Кевина в комментарии неверен и каким он должен быть на самом деле?
Майкл

Спасибо большое !! Это именно то, что я искал
brunobliss

@MarkByers IFNOtNULL (expr1, 1) есть что-нибудь подобное
Нони

25

Вы можете использовать coalesce(column_name,0)вместо просто column_name. coalesceФункция возвращает первое значение , не NULL в списке.

Следует отметить, что подобные функции для каждой строки обычно проблематичны для масштабируемости. Если вы считаете , что ваша база данных может получить быть приличного размера, часто лучше использовать дополнительные столбцы и триггеры , чтобы переместить стоимость от selectдо insert/update.

Это амортизирует стоимость, если предположить, что ваша база данных читается чаще, чем записывается (и большинство из них).


Это происходит один раз в неделю, чтобы выставить счет всем клиентам. Данные записываются всю неделю, затем в определенное время их вычисляют и выставляют счета. Думайте об этом как о сервисе подписки. Вы можете вносить изменения в течение срока действия расчетного периода, и ваша активность начисляется через соответствующие интервалы.
Кевин

Я бы добавил, что в этой ситуации я бы предпочел объединение, потому что это одинаковый синтаксис для MS и My SQL, тогда как MS SQL - это iSnull, а MySQL - iFnull, если это имеет значение для кого-либо. (MySQL ISNULL - это функция, отличная от ISNULL в MS SQL)
Крейг Джейкобс,

11

Ни один из приведенных выше ответов не был для меня полным. Если ваше поле названо field, то селектор должен быть следующим:

IFNULL(`field`,0) AS field

Например, в запросе SELECT:

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

Надеюсь, что это может помочь кому-то не тратить время.


5

Вы можете попробовать что-то вроде этого

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

Атрибут X считается пустым, если он является пустой строкой, поэтому после этого вы можете объявить ноль вместо последнего значения. В другом случае он останется в своем первоначальном значении.

Во всяком случае, просто чтобы дать другой способ сделать это.


Это отлично сработало для меня в середине SELECT против обычного IFNULL (var, 0)
ajankuv

5

Да, функция IFNULL будет работать для достижения желаемого результата.

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;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.