Lab: Count Missing Phone Numbers
คุณได้รับข้อมูลนักเรียน 8 คน และต้องตอบคำถามเดียว: “มีนักเรียนกี่คนที่ไม่มีเบอร์โทร?” — ฟังดูง่าย แต่คำตอบขึ้นอยู่กับว่าคุณนิยาม “ไม่มี” ยังไง
เวลาที่ใช้: ~20 นาที
ข้อมูล
Section titled “ข้อมูล”| student_id | name | phone |
|---|---|---|
| 001 | Ploy | 0812345678 |
| 002 | Som | (ว่าง) |
| 003 | Tong | |
| 004 | Fah | 0898765432 |
| 005 | Bank | (ว่าง) |
| 006 | Mint | 0 |
| 007 | Pim | 0856781234 |
| 008 | Ice | (ว่าง) |
หมายเหตุ:
- Som (002) — ยังไม่เคยกรอกเบอร์ → NULL
- Tong (003) — กรอกแล้วลบออก → empty string
"" - Bank (005) — ยังไม่เคยกรอกเบอร์ → NULL
- Mint (006) — กรอกผิดเป็น
0→ zero (มีค่า แต่ไม่ใช่เบอร์จริง) - Ice (008) — ยังไม่เคยกรอกเบอร์ → NULL
คำสั่ง
Section titled “คำสั่ง”-
เตรียมข้อมูลในแต่ละเครื่องมือ (ดู tab ด้านล่าง)
-
ตอบ 3 คำถาม:
- คำถาม A: มีนักเรียนกี่คนที่ phone เป็น NULL / blank?
- คำถาม B: มีนักเรียนกี่คนที่ phone เป็น empty string?
- คำถาม C: มีนักเรียนกี่คนที่ “ไม่มีเบอร์โทรที่ใช้ได้” (รวมทั้ง NULL, empty string, และ 0)?
-
เปรียบเทียบคำตอบจากทุกเครื่องมือ — ต้องตรงกัน!
สร้าง sheet ใหม่ พิมพ์ข้อมูลตามนี้:
| A (student_id) | B (name) | C (phone) |
|---|---|---|
| 001 | Ploy | 0812345678 |
| 002 | Som | (เว้นว่าง) |
| 003 | Tong | ="" (พิมพ์สูตร) |
| 004 | Fah | 0898765432 |
| 005 | Bank | (เว้นว่าง) |
| 006 | Mint | 0 |
| 007 | Pim | 0856781234 |
| 008 | Ice | (เว้นว่าง) |
ใช้สูตรเหล่านี้หาคำตอบ:
- คำถาม A:
=COUNTBLANK(C1:C8)ให้เท่าไหร่? แล้ว=COUNTIF(C1:C8,"")ล่ะ? - คำถาม B: ลองใช้
=SUMPRODUCT((C1:C8="")*ISBLANK(C1:C8)=FALSE*1)หรือวิธีอื่น - คำถาม C: ลองรวมทุกเงื่อนไขเข้าด้วยกัน
Hint: COUNTBLANK นับทั้ง blank และ empty string — คุณต้องหาวิธีแยก
#include <stdio.h>#include <string.h>
int main() { // NULL = pointer เป็น NULL // empty string = "" // zero = "0" char *phones[] = { "0812345678", // Ploy NULL, // Som — ไม่เคยกรอก "", // Tong — กรอกแล้วลบ "0898765432", // Fah NULL, // Bank — ไม่เคยกรอก "0", // Mint — กรอกผิด "0856781234", // Pim NULL // Ice — ไม่เคยกรอก }; int n = 8;
int null_count = 0; int empty_count = 0; int unusable_count = 0;
for (int i = 0; i < n; i++) { if (phones[i] == NULL) { null_count++; unusable_count++; } else if (strlen(phones[i]) == 0) { empty_count++; unusable_count++; } else if (strcmp(phones[i], "0") == 0) { unusable_count++; } }
printf("A: NULL count = %d\n", null_count); printf("B: Empty string count = %d\n", empty_count); printf("C: Unusable total = %d\n", unusable_count);
return 0;}ลองรันแล้วดูว่าคำตอบตรงกับ Sheets ไหม
import pandas as pdimport numpy as np
df = pd.DataFrame({ 'student_id': ['001', '002', '003', '004', '005', '006', '007', '008'], 'name': ['Ploy', 'Som', 'Tong', 'Fah', 'Bank', 'Mint', 'Pim', 'Ice'], 'phone': ['0812345678', None, '', '0898765432', None, '0', '0856781234', None]})
print(df)print()
# คำถาม A: NULL / NaNa = df['phone'].isna().sum()print(f"A: NULL count = {a}")
# คำถาม B: empty stringb = (df['phone'] == '').sum()print(f"B: Empty string count = {b}")
# คำถาม C: ไม่มีเบอร์ที่ใช้ได้ (NULL + empty + "0")c = df['phone'].isna().sum() + (df['phone'] == '').sum() + (df['phone'] == '0').sum()print(f"C: Unusable total = {c}")ลองรันแล้วเปรียบเทียบ
Bonus: ลองใช้วิธีอื่น:
# วิธีสั้นกว่าusable = df['phone'].notna() & (df['phone'] != '') & (df['phone'] != '0')print(f"Usable phones: {usable.sum()}")print(f"Unusable: {(~usable).sum()}")CREATE TABLE students ( student_id VARCHAR(3), name VARCHAR(50), phone VARCHAR(20));
INSERT INTO students VALUES ('001', 'Ploy', '0812345678');INSERT INTO students VALUES ('002', 'Som', NULL);INSERT INTO students VALUES ('003', 'Tong', '');INSERT INTO students VALUES ('004', 'Fah', '0898765432');INSERT INTO students VALUES ('005', 'Bank', NULL);INSERT INTO students VALUES ('006', 'Mint', '0');INSERT INTO students VALUES ('007', 'Pim', '0856781234');INSERT INTO students VALUES ('008', 'Ice', NULL);
-- คำถาม A: NULLSELECT COUNT(*) AS null_countFROM studentsWHERE phone IS NULL;
-- คำถาม B: empty stringSELECT COUNT(*) AS empty_countFROM studentsWHERE phone = '';
-- คำถาม C: ไม่มีเบอร์ที่ใช้ได้SELECT COUNT(*) AS unusable_countFROM studentsWHERE phone IS NULL OR phone = '' OR phone = '0';ลองรันแล้วเปรียบเทียบกับเครื่องมืออื่น
Bonus: ลองใช้ COALESCE:
SELECT name, COALESCE(phone, 'N/A') AS phone_displayFROM students;-- COALESCE แปลง NULL → 'N/A' แต่ไม่จัดการ empty string!ดูเฉลย
คำตอบ:
- A: NULL / blank = 3 คน (Som, Bank, Ice)
- B: Empty string = 1 คน (Tong)
- C: ไม่มีเบอร์ที่ใช้ได้ = 5 คน (Som, Tong, Bank, Mint, Ice)
ผลลัพธ์ต้องตรงกันทุกเครื่องมือ:
| Sheets | Python | SQL | |
|---|---|---|---|
| A (NULL) | COUNTBLANK = 4 (!) ต้องหักลบ empty string | isna().sum() = 3 | phone IS NULL → 3 |
| B (empty) | ต้องคำนวณแยก = 1 | (phone == '').sum() = 1 | phone = '' → 1 |
| C (unusable) | 5 | 5 | 5 |
Sheets trap: COUNTBLANK(C1:C8) ให้ 4 ไม่ใช่ 3 — เพราะมันนับทั้ง blank (3 คน) และ empty string (1 คน) รวมกัน!
ถ้าต้องการนับแค่ “blank จริงๆ” ใน Sheets ต้องใช้:
=COUNTIF(C1:C8,"") - SUMPRODUCT((C1:C8="")*NOT(ISBLANK(C1:C8))*1)หรือวิธีง่ายกว่า:
=SUMPRODUCT(ISBLANK(C1:C8)*1)ซึ่งให้ 3 — ถูกต้อง
บทเรียนสำคัญ: COUNTBLANK ใน Sheets = NULL + empty string — อย่าใช้มันถ้าต้องการนับแค่ NULL!