Kembalikan 0 jika bidang isian dalam MySQL


160

Di MySQL, apakah ada cara untuk mengatur bidang "total" menjadi nol jika bidang tersebut NULL?

Inilah yang saya miliki:

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;

Data keluar dengan baik, kecuali bidang NULL seharusnya 0.

Bagaimana saya bisa mengembalikan 0 untuk NULL di MySQL?

Jawaban:


327

Gunakan IFNULL :

IFNULL(expr1, 0)

Dari dokumentasi:

Jika expr1 bukan NULL, IFNULL () mengembalikan expr1; jika tidak mengembalikan expr2. IFNULL () mengembalikan nilai numerik atau string, tergantung pada konteks di mana ia digunakan.


Apakah itu IFNULL ((SELECT SUM (uop.price * uop.qty)) DARI uc_order_products uop WHERE uo.order_id = uop.order_id) SEBAGAI products_subtotal, 0)?
Kevin

2
@Kevin: Tidak - alias ada di akhir.
Mark Byers

2
@MarkByers dapatkah Anda menunjukkan mengapa contoh Kevin dalam komentar itu salah dan seperti apa seharusnya?
Michael

Terima kasih banyak !! Ini persis apa yang saya cari
brunobliss

@MarkByers IFNOtNULL (exp1, 1) apakah ada hal seperti itu
Noni

25

Anda bisa menggunakan coalesce(column_name,0)bukan hanya column_name. The coalescefungsi mengembalikan nilai non-NULL pertama dalam daftar.

Saya harus menyebutkan bahwa fungsi per-baris seperti ini biasanya bermasalah untuk skalabilitas. Jika Anda berpikir bahwa basis data Anda mungkin menjadi ukuran yang layak, sering kali lebih baik menggunakan kolom tambahan dan pemicu untuk memindahkan biaya dari selectke insert/update.

Ini mengamortisasi biaya dengan asumsi database Anda lebih sering dibaca daripada yang tertulis (dan kebanyakan dari mereka adalah).


Ini terjadi seminggu sekali untuk menagih semua pelanggan. Data ditulis sepanjang minggu, lalu pada waktu tertentu, dihitung dan ditagih. Anggap saja seperti layanan berlangganan. Anda dapat membuat perubahan selama masa penagihan, dan aktivitas Anda dibebankan pada interval yang sesuai.
Kevin

Saya akan menambahkan bahwa dalam situasi ini saya lebih suka menyatu karena itu sintaks yang sama untuk MS dan SQL Saya, sedangkan MS SQL adalah iSnull dan MySQL adalah iFnull, jika itu penting bagi siapa pun. (MySQL ISNULL adalah fungsi yang berbeda dari MS SQL ISNULL)
Craig Jacobs

11

Tidak ada jawaban di atas yang lengkap untuk saya. Jika bidang Anda bernama field, maka pemilihnya harus yang berikut:

IFNULL(`field`,0) AS field

Misalnya dalam kueri SELECT:

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

Semoga ini bisa membantu seseorang untuk tidak membuang waktu.


5

Anda dapat mencoba sesuatu seperti ini

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

Atribut X dianggap kosong jika itu adalah String kosong, jadi setelah itu Anda dapat mendeklarasikan sebagai nol, bukan nilai terakhir. Dalam kasus lain, itu akan tetap nilai aslinya.

Bagaimanapun, hanya untuk memberikan cara lain untuk melakukan itu.


Ini bekerja dengan baik untuk saya di tengah SELECT vs IFNULL normal (var, 0)
ajankuv

5

Ya, fungsi IFNULL akan berfungsi untuk mencapai hasil yang Anda inginkan.

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;
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.