IS NULL, IS NOT NULL และความเท่าเทียบที่ปลอดภัยต่อ NULL
ตรวจสอบ NULL อย่างถูกต้อง และใช้ตัวดำเนินการที่ปลอดภัยต่อ NULL ตามแต่ละภาษาถิ่น
IS NULL, IS NOT NULL และความเท่าเทียบที่ปลอดภัยต่อ NULL เป็นบทเรียน SQL Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
การตรวจสอบ NULL อย่างถูกวิธี
บทเรียนก่อนหน้าแสดงให้เห็นว่าคุณไม่สามารถใช้ = เพื่อค้นหา NULL ได้ แล้วจะตรวจสอบ NULL ได้อย่างไร คำตอบคือใช้เงื่อนไขเฉพาะ IS NULL และ IS NOT NULL
นี่เป็นวิธีที่ถูกต้องและใช้ได้กับหลายระบบเพียงสองวิธีในการตรวจสอบค่าที่หายไป และผู้สัมภาษณ์จะไม่ยอมรับ col = NULL ทุกครั้งที่พบ
บทเรียนนี้ครอบคลุม IS NULL, IS NOT NULL, กลุ่มคำสั่ง IS DISTINCT FROM และตัวดำเนินการตรวจสอบความเท่ากันที่รองรับ NULL ซึ่งแตกต่างกันไปตามแต่ละระบบ การรู้จักความแตกต่างระหว่างระบบฐานข้อมูลเป็นสัญญาณชัดเจนถึงความเชี่ยวชาญระดับอาวุโส
IS NULL และ IS NOT NULL
IS NULL ให้ผลเป็น TRUE เมื่อค่าเป็น NULL และเป็น FALSE ในกรณีอื่น ที่สำคัญคือคำสั่งนี้ไม่เคยให้ผลเป็น UNKNOWN จึงสามารถใช้โดยตรงใน WHERE ได้อย่างปลอดภัย
IS NOT NULL เป็นส่วนเติมเต็มที่ตรงกันทุกประการ: ให้ผลเป็น TRUE สำหรับค่าที่มีอยู่จริง และเป็น FALSE สำหรับ NULL
เงื่อนไขเหล่านี้เป็นเครื่องมือหลักในการจัดการ NULL เป็นส่วนหนึ่งของภาษาเอสคิวแอลมาตรฐาน และทำงานเหมือนกันใน MySQL, โพสต์เกรส, เซิร์ฟเวอร์เอสคิวแอล, ออราเคิล และเอสคิวไลต์
-- Find employees with no recorded bonus
SELECT name FROM employees WHERE bonus IS NULL;
-- Find employees that do have a bonus
SELECT name FROM employees WHERE bonus IS NOT NULL;เหตุใด คอลัมน์ = NULL จึงผิดเสมอ
นี่เป็นจุดหลอกในการสัมภาษณ์ที่พบได้แน่นอน ผู้เข้าสัมภาษณ์เขียน WHERE bonus = NULL โดยคาดว่าจะค้นหาโบนัสที่หายไป แต่กลับได้ผลลัพธ์เป็น ศูนย์แถว
จำตรรกะสามค่าไว้: bonus = NULL เป็น UNKNOWN สำหรับทุกแถว รวมถึงแถวที่มีค่า NULL ด้วย เพราะไม่มีสิ่งใดเท่ากับค่าที่ไม่ทราบค่า WHERE จะเก็บไว้เฉพาะ TRUE ดังนั้นจึงไม่มีแถวใดตรงตามเงื่อนไข
ฐานข้อมูลบางระบบในโหมดที่ไม่เป็นมาตรฐานอาจเปลี่ยน = NULL เป็น IS NULL ให้โดยไม่มีการแจ้งเตือน แต่คุณต้องไม่พึ่งพาพฤติกรรมนั้น ให้เขียน IS NULL อย่างชัดเจนเสมอ
-- WRONG: returns zero rows, bonus = NULL is UNKNOWN for all
SELECT name FROM employees WHERE bonus = NULL;
-- RIGHT:
SELECT name FROM employees WHERE bonus IS NULL;การนับค่า NULL และค่าที่ไม่ใช่ NULL
งานทั่วไปของนักวิเคราะห์คือการตรวจสอบคุณภาพข้อมูล: คอลัมน์หนึ่งมีข้อมูลครบถ้วนเพียงใด ให้ใช้ IS NULL ร่วมกับ COUNT เพื่อรายงานค่าที่หายไป
สังเกตความแตกต่างนี้: COUNT(*) นับทุกแถว ขณะที่ COUNT(bonus) นับเฉพาะโบนัสที่ไม่ใช่ NULL ผลต่างระหว่างสองค่านี้เท่ากับจำนวน NULL ซึ่งเราจะกลับมาพูดถึงอีกครั้งในบทเรียนเรื่องการรวมค่า
SELECT
COUNT(*) AS total_rows,
COUNT(bonus) AS with_bonus,
COUNT(*) - COUNT(bonus) AS missing_bonus,
SUM(CASE WHEN bonus IS NULL THEN 1 ELSE 0 END) AS missing_check
FROM employees;ปัญหาที่ความเท่ากันซึ่งรองรับ NULL อย่างปลอดภัยช่วยแก้ไข
สมมติว่าคุณต้องการจับคู่คอลัมน์สองคอลัมน์ และถือว่า 'NULL ทั้งสองค่า' เป็นคู่ที่ตรงกัน การใช้ a = b แบบปกติทำไม่ได้: เมื่อทั้งสองค่าเป็น NULL ผลลัพธ์จะเป็น UNKNOWN คู่ดังกล่าวจึงถูกตัดออก ทั้งที่ตามความเข้าใจทั่วไปควรถือว่า 'เหมือนกัน'
กรณีนี้เกิดขึ้นเมื่อต้องเปรียบเทียบแถวเก่ากับแถวใหม่เพื่อค้นหาการเปลี่ยนแปลง หรือเมื่อเชื่อมตารางด้วยคอลัมน์ที่อาจไม่มีค่า คุณต้องใช้การเปรียบเทียบที่ทำให้ เมื่อ NULL เท่ากับ NULL จะเป็น TRUE และ เมื่อ NULL เทียบกับค่าหนึ่งจะเป็น FALSE นี่คือสิ่งที่การตรวจสอบความเท่ากันที่รองรับ NULL อย่างปลอดภัยมอบให้
-- Goal: change-detection where two NULLs count as equal
-- Plain equality fails when both sides are NULL:
-- NULL = NULL -> UNKNOWN (treated as not-equal)
SELECT * FROM old_t o JOIN new_t n ON o.id = n.id
WHERE o.note = n.note; -- misses rows where both notes are NULLIS DISTINCT FROM (ภาษาเอสคิวแอลมาตรฐาน)
การเปรียบเทียบที่รองรับ NULL อย่างปลอดภัยตามมาตรฐาน ANSI คือ IS DISTINCT FROM และรูปแบบตรงข้ามคือ IS NOT DISTINCT FROM ทั้งสองรูปแบบรองรับในโพสต์เกรส, เซิร์ฟเวอร์เอสคิวแอล (2022 ขึ้นไป) และระบบอื่น ๆ
a IS NOT DISTINCT FROM bหมายถึง 'เท่ากัน โดยถือว่า NULL = NULL เป็นค่าที่เท่ากัน'a IS DISTINCT FROM bหมายถึง 'แตกต่างกัน โดยถือว่า NULL เป็นค่าปกติ'
คำสั่งเหล่านี้ให้ผลเป็น TRUE หรือ FALSE เสมอ ไม่เคยเป็น UNKNOWN จึงใช้ได้อย่างปลอดภัยในทุกบริบทที่ต้องการเงื่อนไข
-- TRUE when notes match, including both NULL
SELECT * FROM old_t o JOIN new_t n ON o.id = n.id
WHERE o.note IS NOT DISTINCT FROM n.note;
-- TRUE when notes differ (NULL vs value counts as different)
SELECT * FROM old_t o JOIN new_t n ON o.id = n.id
WHERE o.note IS DISTINCT FROM n.note;ตัวดำเนินการ <=> ของ MySQL
MySQL มีตัวดำเนินการตรวจสอบความเท่ากันที่รองรับ NULL อย่างปลอดภัยแบบกระชับ เขียนเป็น <=> หรือที่เรียกว่าตัวดำเนินการยานอวกาศ
a <=> b ให้ผลเป็น 1 (TRUE) เมื่อค่าทั้งสองฝั่งเท่ากันหรือเป็น NULL ทั้งคู่ และให้ผลเป็น 0 (FALSE) ในกรณีอื่น ซึ่งเทียบเท่ากับ IS NOT DISTINCT FROM ใน MySQL
หากผู้สัมภาษณ์ถามถึงการจับคู่ที่รองรับ NULL อย่างปลอดภัยใน MySQL โดยเฉพาะ คำตอบตามสำนวนที่ใช้ในระบบนี้ก็คือการใช้ตัวดำเนินการนี้
-- MySQL: 1 when both equal or both NULL
SELECT (NULL <=> NULL) AS both_null, -- 1
(NULL <=> 5) AS null_vs_val, -- 0
(5 <=> 5) AS val_eq; -- 1
SELECT * FROM old_t o JOIN new_t n ON o.id = n.id
WHERE o.note <=> n.note;ชีตสรุปการใช้งานข้ามระบบฐานข้อมูล
ผู้สัมภาษณ์ให้ความสำคัญกับผู้สมัครที่รู้ขอบเขตการใช้งานข้ามระบบฐานข้อมูล ต่อไปนี้คือแผนผังการเปรียบเทียบที่ปลอดภัยกับ NULL:
- ANSI / Postgres / SQL Server 2022+:
IS NOT DISTINCT FROM - MySQL / MariaDB:
<=> - SQLite:
ISและIS NOTใช้เป็นการเปรียบเทียบความเท่ากันที่ปลอดภัยกับ NULL ได้ - Oracle: ไม่มีตัวดำเนินการดั้งเดิม ต้องจำลองการทำงานด้วย
DECODE(a, b, 1, 0) = 1หรือเทคนิคการใช้ COALESCE
เมื่อไม่แน่ใจว่าใช้ระบบใด ให้ใช้รูปแบบที่เขียนขึ้นเองและใช้ข้ามระบบได้ ซึ่งจะแสดงในหัวข้อถัดไป
-- SQLite NULL-safe equality
SELECT * FROM t WHERE a IS b; -- TRUE when both NULL
SELECT * FROM t WHERE a IS NOT b; -- complementการจับคู่กับ NULL แบบปลอดภัยด้วยรูปแบบที่ใช้ข้ามระบบได้
เมื่อไม่มีตัวดำเนินการดั้งเดิมให้ใช้ คุณสามารถสร้างการเปรียบเทียบความเท่ากันที่ปลอดภัยกับ NULL จากองค์ประกอบพื้นฐานได้ รูปแบบที่ใช้ข้ามระบบได้นี้รวมการเปรียบเทียบความเท่ากันตามปกติเข้ากับเงื่อนไขที่ระบุอย่างชัดเจนว่าทั้งสองค่าเป็น NULL
ให้อ่านความหมายว่า “ค่าทั้งสองเท่ากัน หรือทั้งคู่ไม่มีค่า” รูปแบบนี้ใช้ได้กับทุกฐานข้อมูล จึงเป็นคำตอบที่ดีเมื่อผู้สัมภาษณ์ไม่ได้ระบุรูปแบบ SQL ที่ใช้
SELECT *
FROM old_t o JOIN new_t n ON o.id = n.id
WHERE (o.note = n.note)
OR (o.note IS NULL AND n.note IS NULL);
-- Alternative using COALESCE with a sentinel that
-- cannot occur in real data:
-- WHERE COALESCE(o.note, '##NULL##') = COALESCE(n.note, '##NULL##')ตัวอย่างเชิงลึก: คีย์ JOIN ที่ปลอดภัยกับ NULL
กรณีที่มักทำให้พลาดในทางปฏิบัติคือการเชื่อมตารางด้วยคีย์ที่อนุญาตให้ไม่มีค่า หาก region เป็น NULL ได้ทั้งสองฝั่ง การเชื่อมตารางด้วยเงื่อนไขความเท่ากันตามปกติจะตัดคู่แถวเหล่านั้นออกไปโดยไม่แจ้งให้ทราบ เพราะ NULL = NULL ให้ผลเป็น UNKNOWN
หากกฎทางธุรกิจระบุว่า “แถวที่ไม่มีภูมิภาคควรจับคู่กับแถวอื่นที่ไม่มีภูมิภาคได้” คุณต้องทำให้เงื่อนไขการเชื่อมตารางปลอดภัยกับ NULL ระบุสมมติฐานนี้ออกมาอย่างชัดเจนในการสัมภาษณ์ แล้วเลือกตัวดำเนินการให้ตรงกับระบบที่ใช้
-- Postgres / ANSI: match including both-NULL regions
SELECT a.id, b.id
FROM table_a a
JOIN table_b b
ON a.region IS NOT DISTINCT FROM b.region;
-- MySQL equivalent: ON a.region <=> b.regionประเด็นสำหรับพูดในการสัมภาษณ์
หากต้องตอบคำถามเกี่ยวกับการตรวจสอบ NULL ให้ชัดเจนและเป็นระบบ:
- ใช้
IS NULL/IS NOT NULLเสมอ ห้ามใช้= NULL - เงื่อนไขเหล่านี้ให้ผลเป็น TRUE หรือ FALSE เท่านั้น จึงปลอดภัยเมื่อใช้ใน WHERE
- สำหรับการจับคู่แบบ “NULL เท่ากับ NULL” ให้ใช้ IS NOT DISTINCT FROM (ANSI) หรือ <=> (MySQL)
- ระบุรูปแบบ SQL ที่กำลังใช้งาน และเสนอรูปแบบสำรองด้วยเงื่อนไข OR ที่ใช้ข้ามระบบได้เมื่อไม่แน่ใจ
การกล่าวถึงทั้งตัวดำเนินการมาตรฐานและตัวดำเนินการของผู้ผลิตจะแสดงให้เห็นความรู้รอบด้านที่ผู้คัดกรองสังเกตเห็น
ตรวจสอบความเข้าใจอย่างรวดเร็ว
เลือกการเปรียบเทียบที่ปลอดภัยกับ NULL ให้ถูกต้อง
ทบทวน
ตอนนี้คุณสามารถตรวจสอบ NULL ได้อย่างถูกต้องแล้ว:
IS NULL/IS NOT NULLเป็นวิธีตรวจสอบ NULL ที่ถูกต้องและใช้ข้ามระบบได้เพียงวิธีเดียว โดยจะไม่คืนค่า UNKNOWNcol = NULLให้ผลเป็นศูนย์แถวเสมอ เป็นกับดักคลาสสิกในการสัมภาษณ์- การเปรียบเทียบความเท่ากันที่ปลอดภัยกับ NULL จะถือว่า NULL สองค่าเท่ากัน: IS NOT DISTINCT FROM (ANSI/Postgres), <=> (MySQL), IS (SQLite)
- เมื่อไม่มีตัวดำเนินการดังกล่าว ให้ใช้
(a = b) OR (a IS NULL AND b IS NULL)
หัวข้อถัดไป: การแทนค่าเริ่มต้นให้กับ NULL ด้วย COALESCE, NULLIF และฟังก์ชันเฉพาะผู้ผลิตอย่าง ISNULL
คำถามที่พบบ่อย
บทเรียน “IS NULL, IS NOT NULL และความเท่าเทียบที่ปลอดภัยต่อ NULL” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “IS NULL, IS NOT NULL และความเท่าเทียบที่ปลอดภัยต่อ NULL” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “IS NULL, IS NOT NULL และความเท่าเทียบที่ปลอดภัยต่อ NULL”
ตรวจสอบ NULL อย่างถูกต้อง และใช้ตัวดำเนินการที่ปลอดภัยต่อ NULL ตามแต่ละภาษาถิ่น คุณปฏิบัติ SQL Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Interview Prep หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “IS NULL, IS NOT NULL และความเท่าเทียบที่ปลอดภัยต่อ NULL” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน SQL Interview Prep นี้ได้ไหม
ได้ บทเรียน SQL Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ตรรกะสามค่าและ UNKNOWN
- IS NULL, IS NOT NULL และความเท่าเทียบที่ปลอดภัยต่อ NULL
- COALESCE, NULLIF และ ISNULL
- NULL ในฟังก์ชันรวม การเชื่อมตาราง และ DISTINCT