ตรรกะสามค่าและ UNKNOWN
เหตุใด NULL = NULL จึงไม่เป็นจริง และ UNKNOWN แพร่ผ่านเงื่อนไขต่าง ๆ อย่างไร
ตรรกะสามค่าและ UNKNOWN เป็นบทเรียน SQL Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใด NULL จึงทำให้ผู้เข้าสัมภาษณ์พลาด
NULL เป็นสาเหตุอันดับหนึ่งของคำตอบผิดในการสัมภาษณ์งานด้านเอสคิวแอล จุดที่มักพลาดคือการปฏิบัติต่อ NULL เหมือนค่าปกติ ทั้งที่จริงแล้ว NULL หมายถึง 'ไม่ทราบค่า' หรือ 'ไม่มีค่า' ไม่ใช่ศูนย์และไม่ใช่ข้อความว่าง
ผู้สัมภาษณ์ชอบประเด็นนี้ เพราะไวยากรณ์ดูถูกต้อง แต่ผลลัพธ์กลับผิดโดยไม่มีการแจ้งเตือน พวกเขาอาจแสดงตัวกรองที่ 'ควร' คืนแถว แล้วถามว่าทำไมจึงไม่คืนผลลัพธ์ใดเลย
ในบทเรียนนี้ คุณจะสร้างแบบจำลองทางความคิดที่ช่วยตอบคำถามเกี่ยวกับ NULL ได้ทุกแบบ นั่นคือ ตรรกะสามค่า เมื่อคุณเข้าใจว่าการเปรียบเทียบอาจให้ผลเป็น TRUE, FALSE หรือ UNKNOWN แล้ว ประเด็นที่เหลือจะเข้าใจได้ตามมา
NULL ไม่ใช่ค่า
ประโยคเดียวที่สำคัญที่สุดที่ควรพูดในการสัมภาษณ์คือ NULL คือการไม่มีค่า ไม่ใช่ค่าด้วยตัวมันเอง
ดังนั้น คุณจึงไม่สามารถเปรียบเทียบ NULL ด้วย = แบบเดียวกับที่ใช้เปรียบเทียบตัวเลขได้ ฐานข้อมูลไม่อาจทราบได้ว่าค่าที่ไม่ทราบค่าทั้งสองค่านั้นเท่ากันหรือไม่ จึงไม่เลือกยืนยันว่าเป็น TRUE หรือ FALSE
NULL = 5ไม่ใช่ FALSE แต่เป็น UNKNOWNNULL = NULLไม่ใช่ TRUE แต่เป็น UNKNOWNNULL <> NULLก็เป็น UNKNOWN เช่นกัน
นี่คือเหตุผลที่ตัวกรองความเท่ากันแบบตรงไปตรงมาบนคอลัมน์ที่อาจเป็น NULL ทำให้บางแถวถูกตัดออกโดยไม่มีการแจ้งเตือน
ตรรกะสองค่าเทียบกับตรรกะสามค่า
ภาษาการเขียนโปรแกรมส่วนใหญ่ใช้ ตรรกะสองค่า: นิพจน์หนึ่งจะเป็น TRUE หรือ FALSE อย่างใดอย่างหนึ่ง ภาษาเอสคิวแอลเพิ่มผลลัพธ์ที่สามคือ UNKNOWN เมื่อมี NULL เกี่ยวข้องกับการเปรียบเทียบ
ดังนั้น เงื่อนไขใด ๆ ในภาษาเอสคิวแอลอาจประเมินผลได้สามแบบ ได้แก่ TRUE, FALSE หรือ UNKNOWN ส่วนคำสั่ง WHERE จะเก็บแถวไว้ก็ต่อเมื่อเงื่อนไขของแถวนั้นเป็น TRUE เท่านั้น UNKNOWN มีพฤติกรรมเหมือน FALSE ในการกรอง แต่ในทางตรรกะไม่ใช่สิ่งเดียวกัน
ผู้สัมภาษณ์ทดสอบว่าคุณรู้จักความแตกต่างนี้หรือไม่ เพราะ UNKNOWN มีพฤติกรรมภายใต้ NOT แตกต่างจาก FALSE
ตัวกรองที่ตัดแถวออกโดยไม่มีการแจ้งเตือน
นี่คือตัวอย่างอธิบายทีละขั้นแบบคลาสสิก สมมติว่า bonus บางแถวมีค่าเป็น NULL ผู้สรรหาบุคลากรถามว่า 'คำสั่งนี้ควรคืนพนักงานทุกคนที่มีโบนัสไม่ใช่ 1000 ทำไมจึงข้ามพนักงานที่ไม่มีโบนัสไป'
สำหรับแถวที่ bonus เป็น NULL นิพจน์ bonus <> 1000 จะประเมินผลเป็น UNKNOWN ไม่ใช่ TRUE WHERE จะเก็บไว้เฉพาะแถวที่เป็น TRUE ดังนั้นพนักงานเหล่านั้นจึงหายไป
วิธีแก้คือต้องจัดการ NULL อย่างชัดเจน ซึ่งเราจะกล่าวถึงในบทเรียนถัดไป สำหรับตอนนี้ ให้เข้าใจว่าแถวที่หายไปเป็นผลลัพธ์ทางตรรกะ ไม่ใช่ข้อผิดพลาด
SELECT name, bonus
FROM employees
WHERE bonus <> 1000;
-- Rows where bonus IS NULL are excluded:
-- NULL <> 1000 evaluates to UNKNOWN, not TRUENULL ในนิพจน์ AND
ตรรกะสามค่าทำให้ AND มีพฤติกรรมแตกต่างออกไป จดจำกฎนี้ไว้ แล้วคุณจะตอบคำถามเกี่ยวกับตารางค่าความจริงได้ทันที
- TRUE AND UNKNOWN = UNKNOWN
- FALSE AND UNKNOWN = FALSE
- UNKNOWN AND UNKNOWN = UNKNOWN
หลักคิดคือ AND ต้องการ FALSE เพียงค่าเดียวก็สรุปได้แน่ชัดว่าเป็น FALSE ดังนั้น FALSE AND ค่าใด ๆ จึงยังคงเป็น FALSE แต่ TRUE AND ค่าที่ไม่ทราบค่ายังคงเป็นค่าที่ไม่ทราบ เพราะด้านที่เป็น UNKNOWN อาจกลายเป็น TRUE หรือ FALSE ก็ได้
-- If status = 'active' is TRUE but bonus = 100 is UNKNOWN:
SELECT *
FROM employees
WHERE status = 'active' AND bonus = 100;
-- Combined result is UNKNOWN, so the row is NOT returnedNULL ในนิพจน์ OR
OR มีหลักการตรงข้ามกับ AND โดยต้องการ TRUE เพียงค่าเดียวก็สรุปได้แน่ชัดว่าเป็น TRUE ดังนั้น TRUE จึงทำให้ UNKNOWN ไม่มีผลต่อคำตอบ
- TRUE OR UNKNOWN = TRUE
- FALSE OR UNKNOWN = UNKNOWN
- UNKNOWN OR UNKNOWN = UNKNOWN
ดังนั้น แถวหนึ่งยังคงตรงตามเงื่อนไข OR ได้ แม้เงื่อนไขย่อยหนึ่งจะเป็น UNKNOWN ตราบใดที่อีกเงื่อนไขหนึ่งเป็น TRUE อย่างแท้จริง นี่เป็นคำถามต่อยอดที่พบบ่อยหลังจากคำถามเรื่อง AND
SELECT *
FROM employees
WHERE department = 'Sales' OR bonus = 100;
-- A Sales employee with NULL bonus:
-- TRUE OR UNKNOWN = TRUE, so the row IS returnedNOT สลับค่า TRUE/FALSE แต่ไม่เปลี่ยน UNKNOWN
นี่คือประเด็นละเอียดอ่อนที่ผู้สัมภาษณ์มักเก็บไว้ถามเป็นข้อสุดท้าย NOT เปลี่ยน TRUE เป็น FALSE และเปลี่ยน FALSE เป็น TRUE แต่ NOT UNKNOWN ยังคงเป็น UNKNOWN
นี่คือเหตุผลที่คุณไม่สามารถครอบเงื่อนไขที่ไม่ผ่านด้วย NOT เพื่อกลับผลลัพธ์ได้ หาก bonus = 1000 เป็น UNKNOWN สำหรับแถวที่มีค่า NULL แล้ว NOT (bonus = 1000) ก็ยังเป็น UNKNOWN และแถวนั้นยังคงถูกตัดออก
การปฏิเสธเงื่อนไขไม่ช่วยกู้คืนแถวที่มี NULL มีเพียงการทดสอบ IS NULL อย่างชัดเจนเท่านั้นที่ทำได้
-- For a row where bonus IS NULL:
-- bonus = 1000 -> UNKNOWN
-- NOT (bonus = 1000) -> UNKNOWN (still excluded)
SELECT * FROM employees WHERE NOT (bonus = 1000);ตัวอย่างอธิบายทีละขั้น: กับดัก NOT IN
นี่เป็นโจทย์เกี่ยวกับ NULL ที่ถูกถามบ่อยที่สุดข้อหนึ่ง การใช้ NOT IN กับรายการที่มี NULL จะไม่คืนแถวใดเลย ทำให้ผู้เข้าสัมภาษณ์ที่คาดว่าจะข้าม NULL ไปต้องประหลาดใจ
เบื้องหลังนั้น x NOT IN (1, 2, NULL) จะถูกขยายเป็น x <> 1 AND x <> 2 AND x <> NULL การเปรียบเทียบส่วนสุดท้ายเป็น UNKNOWN และ TRUE AND TRUE AND UNKNOWN จะยุบเหลือ UNKNOWN ดังนั้นจึงไม่มีสิ่งใดผ่านเกณฑ์
ทางเลือกที่ปลอดภัยคือ NOT EXISTS ซึ่งไม่ประสบปัญหานี้
-- Returns ZERO rows if the subquery yields any NULL
SELECT name
FROM employees
WHERE manager_id NOT IN (SELECT manager_id FROM managers);
-- Each comparison against NULL becomes UNKNOWN,
-- and the AND-chain collapses to UNKNOWN for every row.เหตุใด UNKNOWN จึงมีพฤติกรรมเหมือน FALSE ใน WHERE
คำถามต่อยอดที่พบบ่อยคือ 'ถ้า UNKNOWN ไม่ใช่ FALSE แล้วทำไมแถวจึงถูกตัดออกเหมือนแถวที่เป็น FALSE'
คำตอบที่แน่ชัดคือ WHERE, ON และ HAVING ล้วนใช้กฎ เก็บเฉพาะ TRUE ทั้ง FALSE และ UNKNOWN ไม่ผ่านการทดสอบนั้น ดังนั้นในแง่ของการกรองจึงดูเหมือนกัน
ความแตกต่างจะเห็นได้เมื่อใช้การปฏิเสธเงื่อนไขและข้อจำกัด CHECK ข้อจำกัด CHECK จะยอมรับแถวเมื่อเงื่อนไขเป็น TRUE หรือ UNKNOWN ดังนั้น NULL จึงอาจผ่านข้อจำกัด CHECK ที่คุณคิดว่าจะขัดขวางไว้ได้
-- CHECK passes on TRUE or UNKNOWN, so NULL salary is allowed:
-- CONSTRAINT salary_positive CHECK (salary > 0)
-- INSERT ... salary = NULL -> NULL > 0 is UNKNOWN -> allowedตัวอย่างเชิงลึก: COUNT กับช่องว่างระหว่างจำนวนและค่าความจริง
ลองเชื่อมโยงทั้งหมดเข้ากับโจทย์สัมภาษณ์ที่สมจริง 'เรามีพนักงาน 100 คน SELECT COUNT(*) WHERE bonus = 100 ให้ผลลัพธ์เป็น 30 และ WHERE bonus <> 100 ให้ผลลัพธ์เป็น 50 อีก 20 คนอยู่ที่ไหน'
พนักงานอีก 20 คนมีโบนัสเป็น NULL ทั้ง = 100 และ <> 100 ไม่เป็น TRUE สำหรับพวกเขา แต่เป็น UNKNOWN ทั้งคู่ จึงไม่ผ่านตัวกรองทั้งสองแบบ
การตอบว่า 'กลุ่มย่อยรวมกันไม่เท่ากับยอดรวม เพราะ NULL ไม่ผ่านเงื่อนไขใดเลย' คือคำตอบที่ผู้สัมภาษณ์ต้องการอย่างแท้จริง
SELECT
COUNT(*) FILTER (WHERE bonus = 100) AS eq_100,
COUNT(*) FILTER (WHERE bonus <> 100) AS ne_100,
COUNT(*) FILTER (WHERE bonus IS NULL) AS null_bonus,
COUNT(*) AS total
FROM employees;ประเด็นสำหรับพูดในการสัมภาษณ์
เมื่อพบเรื่องตรรกะของ NULL ให้กล่าวประเด็นเหล่านี้เพื่อแสดงความเข้าใจระดับอาวุโส:
- NULL หมายถึง ไม่ทราบค่า การเปรียบเทียบกับ NULL ให้ผลเป็น UNKNOWN
- ภาษาเอสคิวแอลใช้ ตรรกะสามค่า: TRUE, FALSE, UNKNOWN
- WHERE, ON และ HAVING เก็บไว้ เฉพาะ TRUE เท่านั้น
NOT UNKNOWNยังคงเป็น UNKNOWN ดังนั้นการปฏิเสธเงื่อนไขจึงไม่ช่วยกู้คืนแถวที่มี NULLNOT INที่มี NULL แม้แต่ค่าเดียวจะไม่คืนแถวใดเลย ควรเลือกใช้NOT EXISTS
อธิบายแบบจำลองก่อน แล้วจึงไล่ดูตารางค่าความจริงตามลำดับ การเรียงลำดับเช่นนี้แสดงว่าคุณเข้าใจเหตุผลเบื้องหลัง ไม่ได้รู้เพียงกลเม็ดเท่านั้น
ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจตรรกะสามค่าของคุณ
สรุปทบทวน
ตอนนี้คุณมีแบบจำลองทางความคิดหลักเกี่ยวกับ NULL แล้ว:
- NULL คือ ไม่ทราบค่า ไม่ใช่ค่า ห้ามเปรียบเทียบด้วย
=หรือ<> - ภาษาเอสคิวแอลเป็นระบบ สามค่า: เงื่อนไขคืนค่าเป็น TRUE, FALSE หรือ UNKNOWN
- ส่วนคำสั่งกรองจะเก็บไว้ เฉพาะ TRUE เท่านั้น แถวที่เป็น UNKNOWN จะหายไปเช่นเดียวกับแถวที่เป็น FALSE
NOTสลับ TRUE และ FALSE แต่ปล่อย UNKNOWN ไว้เหมือนเดิม- กับดัก
NOT IN+ NULL จะคืนศูนย์แถว ให้เลือกใช้NOT EXISTS
บทถัดไป: วิธีที่ถูกต้องในการตรวจสอบ NULL ด้วย IS NULL, IS NOT NULL และตัวดำเนินการตรวจสอบความเท่ากันที่รองรับ NULL อย่างปลอดภัย
คำถามที่พบบ่อย
บทเรียน “ตรรกะสามค่าและ UNKNOWN” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ตรรกะสามค่าและ UNKNOWN” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ตรรกะสามค่าและ UNKNOWN”
เหตุใด NULL = NULL จึงไม่เป็นจริง และ UNKNOWN แพร่ผ่านเงื่อนไขต่าง ๆ อย่างไร คุณปฏิบัติ SQL Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Interview Prep หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “ตรรกะสามค่าและ UNKNOWN” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน SQL Interview Prep นี้ได้ไหม
ได้ บทเรียน SQL Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ตรรกะสามค่าและ UNKNOWN
- IS NULL, IS NOT NULL และความเท่าเทียบที่ปลอดภัยต่อ NULL
- COALESCE, NULLIF และ ISNULL
- NULL ในฟังก์ชันรวม การเชื่อมตาราง และ DISTINCT