Tag Archive Class Interval

Byphunsanit

คณิตศาสตร์: อันตรภาคชั้น (Class Interval) แบบ 1

การใช้ อันตรภาคชั้น (Class Interval) ใน Database มักเกิดขึ้นเมื่อเราต้องการจัดการกับข้อมูลเชิงปริมาณที่มีความละเอียดสูง (เช่น อายุ, รายได้, หรือคะแนนสอบ) แล้วต้องการจัดกลุ่มเพื่อให้ง่ายต่อการทำรายงาน (Reporting) หรือการวิเคราะห์ข้อมูล (Analytics) หรือการกำหนด config หรือเกี่ยวข้องกับกฏหมาย


1 การเก็บข้อมูลดิบ (Raw Data) แล้วจัดกลุ่มผ่าน Query

sample idbirthday
11959-03-18
21982-08-05
31956-06-07
41983-11-27
52011-03-15

วิธีนี้เป็นวิธีที่ยืดหยุ่นที่สุด โดยใน Table จะเก็บค่าจริงเอาไว้ แล้วใช้คำสั่ง SQL ในการแบ่งช่วงตอนดึงข้อมูลออกมา

  • ข้อดี: ข้อมูลไม่สูญเสียความละเอียด สามารถเปลี่ยนช่วงอายุหรือเกณฑ์การแบ่งได้ตลอดเวลา
  • เทคนิคที่ใช้: ใช้คำสั่ง CASE WHEN

ตัวอย่าง


การจัดกลุ่มตาม “ความรับผิดทางอาญา” (Criminal Liability)

เหมาะสำหรับการวิเคราะห์กลุ่มผู้ใช้ในเชิงการคุ้มครองเด็กและเยาวชน

SELECT 
    CASE 
        WHEN age < 12 THEN 'ไม่ต้องรับโทษอาญา (ม.73)'
        WHEN age >= 12 AND age < 15 THEN 'ไม่ต้องรับโทษ (แต่ใช้มาตรการพิเศษ)'
        WHEN age >= 15 AND age < 18 THEN 'รับผิดชอบเพิ่มขึ้น (ลดโทษกึ่งหนึ่ง)'
        WHEN age >= 18 AND age < 20 THEN 'เยาวชนใกล้บรรลุ (ลดโทษ 1/3 หรือ กึ่งหนึ่ง)'
        ELSE 'ผู้ใหญ่ (รับโทษเต็ม)'
    END AS criminal_status,
    COUNT(*) AS total_cases
FROM Users
GROUP BY criminal_status;

การจัดกลุ่มตาม “ความสามารถในการทำนิติกรรม” (Legal Capacity)

เหมาะสำหรับระบบ Member หรือการตรวจสอบสิทธิในการทำธุรกรรม/สัญญา

SELECT 
    CASE 
        WHEN age < 7 THEN 'เด็กเล็ก (ยังไม่ต้องทำบัตร)'
        WHEN age >= 7 AND age < 15 THEN 'เด็ก (มีบัตรประชาชน)'
        WHEN age >= 15 AND age < 17 THEN 'เยาวชน (ทำพินัยกรรม/เริ่มทำงานได้)'
        WHEN age >= 17 AND age < 20 THEN 'ผู้เยาว์ (สมรสได้เมื่อผู้ปกครองยินยอม)'
        WHEN age >= 20 AND age < 60 THEN 'บรรลุนิติภาวะ (ทำนิติกรรมได้สมบูรณ์)'
        ELSE 'วัยเกษียณ (รับเบี้ยยังชีพ)'
    END AS legal_capacity_group,
    COUNT(*) AS user_count
FROM Users
GROUP BY legal_capacity_group;

จะสังเกตว่า

  1. เราเก็บข้อมูลโดยใช้ วันเกิด แต่ใช้อายุในการคํานวณเพราะ
    1. วันเกิดเป็นข้อมูลคงที่ ถ้ามาเปิดดูในอีกปี วันเกิดก็ยังคงเดิม
    2. กฏหมายระบุเป็นช่วงอายุเป็นหลัก แต่เราเสามารถหาอายุได้จากการที่ เอาวันที่ปัจจุบันหรือช่วงเกิดเหตุมาใช้ในการหาอายุได้
  2. Boundary Handling: สังเกตว่าผมใช้ age >= 12 AND age < 15 แทนการใช้ BETWEEN 12 AND 15 เพราะ BETWEEN ใน SQL จะนับรวมหัวท้าย (Inclusive) ซึ่งอาจทำให้ข้อมูลซ้อนทับกันได้หากเก็บอายุเป็นทศนิยมหรือวันเกิด การใช้ < (น้อยกว่า) จะช่วยแบ่งช่วงให้ขาดจากกันได้ชัดเจนกว่า (เช่น คนที่อายุ 14 ปี 364 วัน จะยังตกอยู่ในกลุ่มไม่ต้องรับโทษ)
  3. คำนวณจากวันเกิด: ในโลกความเป็นจริง เรามักไม่เก็บอายุ (age) เป็น Integer ในตาราง เพราะอายุเปลี่ยนทุกปี เราจะเก็บเป็น birth_date แล้วคำนวณอายุขณะ Run query
    • PostgreSQL: EXTRACT(YEAR FROM AGE(birth_date))
    • MySQL: TIMESTAMPDIFF(YEAR, birth_date, CURDATE())
    • SQL Server: DATEDIFF(hour, birth_date, GETDATE())/8766 (หรือสูตรที่แม่นยำกว่าตามความเหมาะสม)

อ่านเพิ่มเติม