Trả về 0 nếu trường là null trong MySQL


160

Trong MySQL, có cách nào để đặt các trường "tổng" thành 0 nếu chúng là NULL không?

Đây là những gì tôi có:

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;

Dữ liệu xuất hiện tốt, ngoại trừ các trường NULL 0.

Làm cách nào tôi có thể trả về 0 cho NULL trong MySQL?

Câu trả lời:


326

Sử dụng IFNULL :

IFNULL(expr1, 0)

Từ tài liệu:

Nếu expr1 không phải là NULL, IFNULL () trả về expr1; nếu không, nó trả về expr2. IFNULL () trả về giá trị số hoặc chuỗi, tùy thuộc vào ngữ cảnh được sử dụng.


Đó có phải là IFNULL ((CHỌN SUM (uop.price * uop.qty) TỪ uc_order_products uop WHERE uo.order_id = uop.order_id) NHƯ sản phẩm_subtotal, 0)?
Kevin

2
@Kevin: Không - bí danh ở cuối.
Mark Byers

2
@MarkByer bạn có thể chỉ ra lý do tại sao ví dụ của Kevin trong bình luận là sai và nó thực sự nên là gì?
Michael

cảm ơn bạn rất nhiều !! Đây chính xác là những gì tôi đang tìm kiếm
brunobliss

@MarkByer IFNOtNULL (expr1, 1) có bất cứ điều gì tương tự
Noni

25

Bạn có thể sử dụng coalesce(column_name,0)thay vì chỉ column_name. Các coalescechức năng trả về giá trị phi NULL đầu tiên trong danh sách.

Tôi nên đề cập rằng các hàm trên mỗi hàng như thế này thường có vấn đề về khả năng mở rộng. Nếu bạn nghĩ rằng cơ sở dữ liệu của bạn có thể có kích thước khá, thì tốt hơn là sử dụng các cột và trình kích hoạt bổ sung để chuyển chi phí từ selectsang insert/update.

Điều này khấu hao chi phí giả định rằng cơ sở dữ liệu của bạn được đọc thường xuyên hơn so với bằng văn bản (và hầu hết trong số đó là).


Điều này xảy ra mỗi tuần một lần để lập hóa đơn cho tất cả khách hàng. Dữ liệu được ghi cả tuần, sau đó tại một thời điểm nhất định, nó được tính toán và lập hóa đơn. Hãy nghĩ về nó giống như một dịch vụ thuê bao. Bạn có thể thực hiện các thay đổi trong nhiệm kỳ của thời hạn thanh toán và hoạt động của bạn được tính phí theo các khoảng thời gian thích hợp.
Kevin

Tôi sẽ nói thêm rằng trong tình huống này tôi muốn kết hợp lại vì đó là cùng một cú pháp cho MS và My SQL, trong khi MS SQL là iSnull và MySQL là iFnull, nếu điều đó quan trọng với bất kỳ ai. (MySQL ISNULL là một chức năng khác với ISNULL của MS SQL)
Craig Jacobs

11

Không có câu trả lời nào ở trên là hoàn chỉnh đối với tôi. Nếu trường của bạn được đặt tên field, vì vậy bộ chọn phải là trường sau:

IFNULL(`field`,0) AS field

Ví dụ: trong truy vấn CHỌN:

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

Hy vọng điều này có thể giúp ai đó không lãng phí thời gian.


5

Bạn có thể thử một cái gì đó như thế này

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

Thuộc tính X được coi là trống nếu đó là một chuỗi rỗng, vì vậy sau đó bạn có thể khai báo là 0 thay vì giá trị cuối cùng. Trong trường hợp khác, nó sẽ vẫn là giá trị ban đầu của nó.

Dù sao, chỉ để đưa ra một cách khác để làm điều đó.


Điều này làm việc cho tôi tuyệt vời ở giữa một CHỌN so với IFNULL bình thường (var, 0)
ajankuv

5

Có chức năng IFNULL sẽ hoạt động để đạt được kết quả mong muốn của bạn.

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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.