ค่า NULL คืออะไร ทำไมโปรแกรมเมอร์ต้องแคร์
เวลาเราเก็บข้อมูลในฐานข้อมูล (ที่เก็บข้อมูลถาวรของแอป) บางครั้งเราก็ไม่มีข้อมูลจะใส่ เช่น ช่องกรอกเบอร์โทรศัพท์ที่ลูกค้าไม่ได้ให้มา ในโลกของ PostgreSQL (ระบบจัดการฐานข้อมูลยอดนิยม) เราจะไม่ใส่เลข 0 หรือเว้นว่างไว้เฉยๆ แต่เราจะใช้สิ่งที่เรียกว่า NULL (ค่าที่แปลว่าไม่มีข้อมูลอยู่จริง)
ลองนึกภาพว่าคุณมีกล่องเปล่าหนึ่งใบ ถ้าคุณเขียนว่า "ว่างเปล่า" ลงในกระดาษแล้วใส่ในกล่อง กล่องนั้นก็ยังมีของอยู่ แต่ถ้าคุณทิ้งกล่องนั้นไว้เฉยๆ ไม่ใส่อะไรเลย นั่นแหละคือ NULL ซึ่งไม่ใช่เลขศูนย์และไม่ใช่ช่องว่าง แต่มันคือการบอกฐานข้อมูลว่า "ข้อมูลตรงนี้ไม่มีตัวตน" ครับ
มือใหม่หลายคนมักพลาดเพราะเผลอเอาค่า NULL ไปบวกเลขหรือเปรียบเทียบกับค่าอื่นตรงๆ ซึ่งมักจะได้ผลลัพธ์ที่ผิดพลาดหรือไม่ได้ข้อมูลที่ต้องการ การเข้าใจเรื่องนี้จะช่วยให้คุณเขียน Query (คำสั่งถามข้อมูล) ได้แม่นยำขึ้น และลดบั๊ก (จุดที่โค้ดทำงานผิดพลาด) ในอนาคตได้มหาศาลเลยล่ะ
การกรองข้อมูลด้วย IS NULL และ IS NOT NULL
เวลาเราต้องการดึงข้อมูลเฉพาะคนที่ไม่ได้กรอกเบอร์โทรศัพท์ เราจะใช้คำสั่ง IS NULL แทนการใช้เครื่องหมายเท่ากับครับ เพราะในฐานข้อมูล NULL ถือเป็นสถานะพิเศษที่การเปรียบเทียบปกติทำไม่ได้ ถ้าคุณเขียนว่า WHERE phone = NULL ผลลัพธ์ที่ได้จะเป็นความว่างเปล่าเสมอ
การใช้ IS NULL จะช่วยให้เราเจาะจงหาแถวข้อมูลที่ไม่มีค่าได้ง่ายๆ ส่วนถ้าเราอยากได้เฉพาะคนที่กรอกข้อมูลมาแล้ว เราก็แค่สลับไปใช้ IS NOT NULL แทน ซึ่งเป็นพื้นฐานที่สำคัญมากในการทำรายงานหรือการดึงข้อมูลลูกค้าไปใช้งานต่อ
ลองดูตัวอย่างการใช้งานจริงกันครับ สมมติว่าเรามีตารางเก็บรายชื่อพนักงาน และต้องการหาคนที่ยังไม่ได้ระบุอีเมลในระบบ เพื่อที่จะส่งประกาศให้มาอัปเดตข้อมูลให้ครบถ้วนก่อนเริ่มงานจริง
-- หาพนักงานที่ยังไม่มีอีเมล
SELECT name FROM employees WHERE email IS NULL;
-- หาพนักงานที่ระบุอีเมลแล้ว
SELECT name FROM employees WHERE email IS NOT NULL;
ส่วนที่ 1: บรรทัดแรกใช้ IS NULL เพื่อกรองเอาเฉพาะแถวที่ช่อง email เป็นค่าว่างจริงๆ ส่วนบรรทัดที่สองใช้ IS NOT NULL เพื่อเอาเฉพาะแถวที่มีข้อมูลอีเมลอยู่
ผลลัพธ์: ถ้าในฐานข้อมูลมี 'สมชาย' ที่ไม่มีอีเมล คำสั่งแรกจะแสดงชื่อ 'สมชาย' ออกมา แต่ถ้าเราสั่งแบบที่สอง ชื่อสมชายจะหายไปจากรายการครับ
จัดการค่าว่างให้เป็นมิตรด้วย COALESCE()
บางครั้งการเห็นค่า NULL ในหน้าเว็บหรือรายงานอาจจะดูไม่สวยงาม หรือทำให้คนใช้งานสับสน COALESCE() (ฟังก์ชันที่เลือกค่าแรกที่ไม่ใช่ NULL มาแสดง) จึงเป็นตัวช่วยพระเอกของเราที่เปลี่ยนค่าว่างให้กลายเป็นคำที่เรากำหนดเองได้ เช่น เปลี่ยนจาก NULL เป็นคำว่า "ไม่ระบุ"
การทำงานของมันคือการไล่ดูค่าที่คุณใส่เข้าไปในวงเล็บจากซ้ายไปขวา ตัวไหนเจอค่าแรกที่ไม่ใช่ NULL มันจะเลือกตัวนั้นมาแสดงทันที ถ้าไม่มีเลยค่อยไปดูตัวถัดไปเรื่อยๆ จนจบ นี่เป็นเทคนิคที่ใช้บ่อยมากในการทำหน้าเว็บให้ดูสะอาดตา
ลองดูตัวอย่างการใช้งานจริง สมมติว่าคุณกำลังทำแอปแสดงรายชื่อสินค้า ถ้าสินค้าไหนไม่มีคำอธิบาย คุณอยากให้แสดงคำว่า "ยังไม่มีคำอธิบายสินค้า" แทน เพื่อไม่ให้หน้าจอแอปของคุณดูแหว่งหรือมีช่องว่างแปลกๆ
-- เปลี่ยนค่า NULL เป็นข้อความที่อ่านเข้าใจง่าย
SELECT product_name, COALESCE(description, 'ยังไม่มีคำอธิบายสินค้า') AS info
FROM products;
ส่วนที่ 1: COALESCE จะเช็คที่ช่อง description ก่อน ถ้ามีข้อมูลก็จะดึงมาแสดง แต่ถ้าเป็น NULL มันจะหยิบข้อความในเครื่องหมายคำพูดมาแทนที่
ผลลัพธ์: รายชื่อสินค้าจะแสดงคู่กับคำอธิบายปกติ แต่ถ้าสินค้าไหนว่างอยู่ คุณจะเห็นคำว่า "ยังไม่มีคำอธิบายสินค้า" ปรากฏขึ้นมาแทนที่ความว่างเปล่าครับ
ใช้ NULLIF() เพื่อป้องกันความผิดพลาด
นอกจากเราจะอยากจัดการค่า NULL แล้ว บางครั้งเราก็อยากเปลี่ยนค่าบางอย่างให้กลายเป็น NULL ด้วย เช่น ถ้าเรามีระบบคำนวณส่วนลด แล้วค่าส่วนลดเป็น 0 ซึ่งอาจจะทำให้การหารเลขในโค้ดเกิดข้อผิดพลาด เราจึงใช้ NULLIF() (ฟังก์ชันที่เปลี่ยนค่าให้เป็น NULL ถ้าค่าที่เปรียบเทียบเท่ากัน) เข้ามาช่วย
NULLIF จะรับค่าสองตัว ถ้าค่าทั้งสองตัวเท่ากัน มันจะส่งค่าออกมาเป็น NULL ทันที แต่ถ้าไม่เท่ากัน มันจะส่งค่าตัวแรกออกมา วิธีนี้ช่วยให้เราคุมข้อมูลให้สะอาดขึ้นก่อนจะนำไปคำนวณต่อในขั้นถัดไปได้เป็นอย่างดี
ลองดูตัวอย่างการใช้คำนวณราคาสินค้า ถ้าเราเผลอมีราคาสินค้าเป็น 0 ซึ่งไม่ควรเป็นไปได้ เราสามารถใช้ NULLIF เปลี่ยน 0 ให้กลายเป็น NULL เพื่อป้องกันไม่ให้ระบบนำไปคำนวณค่าเฉลี่ยแบบผิดๆ
-- เปลี่ยนเลข 0 ให้เป็น NULL เพื่อป้องกันการหารผิดพลาด
SELECT price / NULLIF(discount, 0) AS final_price
FROM sales;
ส่วนที่ 1: NULLIF(discount, 0) จะเช็คว่าถ้า discount เป็น 0 ให้เปลี่ยนเป็น NULL เพื่อให้การคำนวณในโปรแกรมไม่เกิดบั๊กจากการหารด้วยศูนย์ (Division by zero)
ผลลัพธ์: หากส่วนลดเป็น 10 ระบบจะคำนวณปกติ แต่ถ้าส่วนลดเป็น 0 ผลลัพธ์ที่ได้จะเป็น NULL แทนที่จะเป็นข้อผิดพลาดที่ทำให้โปรแกรมพังครับ
ข้อควรระวังสำหรับมือใหม่
จุดที่มือใหม่พลาดบ่อยที่สุดคือการลืมว่า NULL ไม่เท่ากับ NULL ครับ ในทางตรรกะของฐานข้อมูล NULL สองตัววางเทียบกันก็ยังไม่ใช่ค่าที่เท่ากัน ดังนั้นการใช้เครื่องหมาย = เพื่อเช็ค NULL จะไม่เคยทำงานได้จริงเลย
อีกเรื่องคือการทำ JOIN (การเชื่อมตารางข้อมูล) ถ้าข้อมูลในคอลัมน์ที่ใช้เชื่อมกันมีค่า NULL ข้อมูลแถวนั้นมักจะหายไปจากการเชื่อมข้อมูลทันที คุณต้องหมั่นตรวจสอบข้อมูลในฐานข้อมูลเสมอว่ามีค่า NULL ที่ไม่ควรอยู่ตรงไหนบ้าง
วิธีแก้ที่ดีที่สุดคือการวางแผนโครงสร้างฐานข้อมูลให้ชัดเจนตั้งแต่แรก ถ้าคอลัมน์ไหนจำเป็นต้องมีข้อมูลแน่ๆ ให้ใช้คำสั่ง NOT NULL กำกับไว้ตอนสร้างตาราง เพื่อบังคับให้คนกรอกข้อมูลต้องใส่ค่าเสมอ ป้องกันปัญหา NULL ปลอมๆ ที่เราไม่ได้ตั้งใจให้เกิดขึ้น
สรุป: นำไปใช้จริงให้โปรเจกต์ดูเป็นมืออาชีพ
การเข้าใจเรื่อง NULL ไม่ใช่แค่เรื่องของการจัดการข้อมูล แต่มันคือการสร้างความน่าเชื่อถือให้กับซอฟต์แวร์ของคุณ สมมติว่าคุณกำลังทำโปรเจกต์เว็บแอปพลิเคชันแสดงข้อมูลเงินเดือนพนักงาน หากคุณไม่ใช้ COALESCE หน้าเว็บของคุณอาจแสดงช่องว่างเปล่าๆ จนดูเหมือนระบบทำงานผิดพลาด แต่ถ้าคุณใช้ COALESCE(salary, 0) ข้อมูลจะแสดงเป็นเลข 0 ที่ดูเป็นระบบและเป็นระเบียบกว่ามาก
เมื่อคุณเริ่มทำงานจริงในฐานะโปรแกรมเมอร์ การเขียน Query ที่จัดการ NULL ได้อย่างรัดกุมจะทำให้ทีมงานคนอื่นที่มาดูโค้ดต่อจากคุณรู้สึกประทับใจ เพราะมันแสดงถึงความใส่ใจในรายละเอียดเล็กๆ น้อยๆ ซึ่งเป็นคุณสมบัติของโปรแกรมเมอร์ที่เก่งและรอบคอบ
ฝึกฝนด้วยการลองดึงข้อมูลจากโปรเจกต์ที่ทำอยู่ แล้วลองใช้ IS NULL หรือ COALESCE ดูผลลัพธ์ที่เปลี่ยนไป เพียงเท่านี้คุณก็จะก้าวข้ามจากมือใหม่ที่เขียนโค้ดแค่ให้รันผ่าน ไปสู่คนที่เข้าใจการจัดการข้อมูลในระดับมืออาชีพได้ไม่ยากครับ