Null Decision Tree
ค่า “ว่าง” มี 3 แบบที่ต่างกันสิ้นเชิง — ถ้าเลือกผิด ข้อมูลจะผิดเงียบๆ โดยไม่มี error
Decision Tree
Section titled “Decision Tree”3 ค่าว่างที่ต่างกัน
Section titled “3 ค่าว่างที่ต่างกัน”1. NULL / None / Blank — “ไม่รู้ค่า”
Section titled “1. NULL / None / Blank — “ไม่รู้ค่า””ความหมาย: ไม่มีข้อมูล — ไม่ได้หมายความว่าค่าเป็นศูนย์ หรือว่าง แต่หมายความว่า ยังไม่รู้
ตัวอย่างจริง:
- ลูกค้าไม่ได้กรอกเบอร์โทร → phone = NULL (ไม่รู้เบอร์)
- ยังไม่ได้ตรวจคะแนน → score = NULL (ยังไม่รู้คะแนน)
// Blank cell — ไม่ได้พิมพ์อะไรเลย=ISBLANK(A1) → TRUE=A1 = "" → TRUE // ⚠️ Sheets ถือว่า blank = ""=TYPE(A1) → 1 // ⚠️ returns 1 (number) ไม่ใช่ "null"!
// สำคัญ: Sheets ไม่มี NULL จริงๆ!// blank cell ≈ NULL แต่ไม่เหมือน 100%#include <stdio.h>#include <stdlib.h>
int main() { char *null_ptr = NULL; // pointer ที่ไม่ชี้ไปไหน // null_ptr ไม่ใช่ string — มันคือ "ไม่มีข้อมูล"
if (null_ptr == NULL) { printf("No data (NULL pointer)\n"); }
// ⚠️ อย่า dereference NULL pointer! // printf("%s", null_ptr); // CRASH! Segmentation fault
return 0;}import pandas as pdimport numpy as np
# Python null typesx = None # Python's nully = pd.NA # pandas' null (newer, better)z = np.nan # numpy's null (float!)
# ตรวจ nullx is None # True ✅pd.isna(x) # True ✅pd.isna(y) # True ✅pd.isna(z) # True ✅
# ⚠️ อย่าใช้ ==None == None # True (ใช้ได้แต่ไม่ Pythonic)np.nan == np.nan # False! (NaN ไม่เท่ากับตัวเอง!)pd.NA == pd.NA # pd.NA (ไม่ใช่ True!)-- NULL ใน SQL มีกฎพิเศษ:SELECT NULL = NULL; -- NULL (ไม่ใช่ TRUE!)SELECT NULL != NULL; -- NULL (ไม่ใช่ TRUE!)SELECT NULL IS NULL; -- TRUE ✅SELECT NULL IS NOT NULL; -- FALSE
-- NULL ใน aggregate functions:SELECT SUM(NULL); -- NULLSELECT COUNT(NULL); -- 0SELECT COUNT(*); -- นับทุกแถว (รวม NULL)SELECT AVG(column); -- ข้าม NULL อัตโนมัติ2. Empty String — “รู้ว่าว่าง”
Section titled “2. Empty String — “รู้ว่าว่าง””ความหมาย: มีข้อมูล แต่ข้อมูลนั้นว่างเปล่า — ต่างจาก NULL ตรงที่ “ตั้งใจ” ให้ว่าง
ตัวอย่างจริง:
- กรอก note ว่า “ไม่มีอะไร” แล้วลบข้อความออก → note = "" (ตั้งใจว่าง)
- ช่อง middle name ที่กรอกว่าไม่มี → middle_name = "" (ไม่มี middle name)
// พิมพ์สูตร ="" ในเซลล์=ISBLANK(A1) → FALSE // มีสูตรอยู่!=A1 = "" → TRUE // ค่าเป็น empty string=LEN(A1) → 0 // ความยาว 0=COUNTBLANK(A1) → 1 // ⚠️ COUNTBLANK นับ "" ด้วย!char empty[] = ""; // 1 byte: just '\0' (null terminator)char *null_ptr = NULL; // 0 bytes allocated — no memory at all
sizeof(empty); // 1 (มี null terminator)strlen(empty); // 0 (ไม่มีตัวอักษร)
// empty != NULL// empty มีที่อยู่ใน memory (มี 1 byte)// NULL ไม่มีที่อยู่เลยempty = ""nothing = None
len(empty) # 0bool(empty) # False (empty string = falsy)bool(nothing) # False (None = falsy too)
empty == nothing # False!empty is None # False!type(empty) # strtype(nothing) # NoneType
pd.isna(empty) # False! — empty string ไม่ใช่ nullpd.isna(nothing) # TrueSELECT '' IS NULL; -- FALSE (empty string ≠ NULL!)SELECT '' = ''; -- TRUESELECT LENGTH(''); -- 0SELECT COALESCE('', 'fallback'); -- '' (ไม่ใช่ 'fallback'!)-- COALESCE ข้าม NULL แต่ไม่ข้าม empty string
-- ⚠️ Oracle ต่างจาก PostgreSQL!-- Oracle: '' IS NULL → TRUE (Oracle ถือ '' = NULL)-- PostgreSQL: '' IS NULL → FALSE (standard SQL)3. Zero (0) — “รู้ว่าเป็นศูนย์”
Section titled “3. Zero (0) — “รู้ว่าเป็นศูนย์””ความหมาย: ค่าตัวเลข 0 — ไม่ว่าง ไม่ใช่ null เป็นตัวเลขจริงๆ
ตัวอย่างจริง:
- สินค้าราคา 0 บาท (แจกฟรี) → price = 0 (ไม่ใช่ null)
- ยอดเงินคงเหลือ 0 → balance = 0 (มีเงินอยู่ แค่เป็น 0)
- คะแนนสอบ 0 → score = 0 (ทำสอบแล้ว ได้ 0)
// เซลล์ที่มี 0=ISBLANK(A1) → FALSE // 0 ไม่ใช่ blank!=A1 = 0 → TRUE=A1 = "" → FALSE // 0 ≠ ""=TYPE(A1) → 1 // number
// ⚠️ ถ้า format เป็น "Automatic" บางครั้ง 0 อาจดูเหมือนว่าง// Format > Number > Number → จะเห็น 0 ชัดเจนint zero = 0; // ตัวเลข 0 — มีค่าจริงchar null_char = '\0'; // null terminator — ค่า byte เป็น 0 เหมือนกัน
// ⚠️ ใน C, 0 = false ในเงื่อนไขif (zero) { // ไม่เข้าที่นี่ — เพราะ 0 = false}// แต่ 0 ยังเป็น "ค่า" ไม่ใช่ "ไม่มีค่า"zero = 0nothing = Noneempty = ""
bool(zero) # False (0 = falsy)bool(nothing) # Falsebool(empty) # False
# แต่ทั้ง 3 เป็นคนละสิ่งกัน!zero == nothing # Falsezero == empty # Falsepd.isna(zero) # False — 0 ไม่ใช่ missing!
# ใน pandas DataFrame:df['score'].fillna(0) # แทน NULL ด้วย 0# ← ระวัง: 0 กับ NULL ความหมายต่างกัน!SELECT 0 IS NULL; -- FALSE (0 ≠ NULL!)SELECT 0 = ''; -- ERROR หรือ FALSE (ขึ้นกับ DBMS)SELECT 0 = 0; -- TRUE
-- ⚠️ aggregate functions ปฏิบัติกับ 0 ต่างจาก NULL:SELECT AVG(score) FROM (VALUES (100), (0), (NULL)) AS t(score);-- AVG = 50 (ไม่ใช่ 33.3!)-- เพราะ NULL ถูกข้าม แต่ 0 ถูกนับSummary Table
Section titled “Summary Table”| NULL / None / Blank | Empty String "" | Zero 0 | |
|---|---|---|---|
| ความหมาย | ไม่รู้ค่า | รู้ว่าว่าง (ตั้งใจ) | รู้ว่าเป็น 0 |
| Sheets | blank cell | ="" | 0 |
| C | NULL pointer | "" (1 byte: \0) | 0 (integer) |
| Python | None / pd.NA | "" | 0 |
| SQL | NULL | '' | 0 |
| ตรวจด้วย | IS NULL / is None / ISBLANK | = "" / len() == 0 | == 0 |
| SUM ใน SQL | ข้าม (ไม่นับ) | ERROR (ไม่ใช่ตัวเลข) | นับเป็น 0 |
| COUNT ใน SQL | COUNT(col) ข้าม | นับ | นับ |
| AVG ใน SQL | ข้าม (ไม่หาร) | ERROR | หาร (ลดค่า AVG) |
กฎที่ต้องจำ
Section titled “กฎที่ต้องจำ”เมื่อไหร่ใช้อะไร?
Section titled “เมื่อไหร่ใช้อะไร?”| สถานการณ์ | ใช้ | ทำไม |
|---|---|---|
| ลูกค้าไม่ได้กรอกเบอร์ | NULL | ไม่รู้ค่า |
| ลูกค้ากรอก “ไม่มี” แล้วลบ | "" | ตั้งใจว่าง |
| สินค้าราคาฟรี | 0 | มีค่า = ศูนย์ |
| คะแนนสอบยังไม่ประกาศ | NULL | ยังไม่รู้ |
| คะแนนสอบ = 0 | 0 | รู้แล้ว = ศูนย์ |
| หมายเหตุไม่มี | NULL | ไม่มีข้อมูล |
| หมายเหตุว่าง (ตั้งใจ) | "" | มีข้อมูล แค่ว่าง |