Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

คำนวณอายุจาก Date of Birth (DOB) ใน MySQL

Query อายุจาก DOB: หลายวิธีและข้อควรระวัง

วิธีที่ 1: ใช้ DATE_SUB / INTERVAL (ตัวอย่างในบทความ)

CREATE TABLE DemoTable611 (DOB DATE);

INSERT INTO DemoTable611 VALUES
('1996-04-21'), ('2001-01-31'), ('2004-12-21'), ('2000-02-03');

-- หาคนอายุ >= 16 ปี (DOB <= 16 ปีก่อน)
SELECT * FROM DemoTable611 
WHERE DOB >= (CURDATE() - INTERVAL 16 YEAR);

หมายเหตุ: Query นี้หา "เกิดภายใน 16 ปีที่แล้ว" = อายุ < 16 ปี ไม่ใช่ >= 16 ปี

วิธีที่ถูกต้อง: คำนวณอายุจริง

-- อายุปัจจุบัน (ปี)
SELECT 
    DOB,
    TIMESTAMPDIFF(YEAR, DOB, CURDATE()) AS age_years,
    TIMESTAMPDIFF(MONTH, DOB, CURDATE()) AS age_months,
    TIMESTAMPDIFF(DAY, DOB, CURDATE()) AS age_days
FROM DemoTable611;

TIMESTAMPDIFF(unit, start, end) คำนวณความต่างอย่างถูกต้อง (คำนึงถึงวันเกิดปีนี้ผ่านไปยัง)

วิธีเก่า: DATEDIFF + หาร 365.25 (ไม่แม่นยำ)

SELECT FLOOR(DATEDIFF(CURDATE(), DOB) / 365.25) AS approx_age
FROM DemoTable611;

❌ ไม่แม่นยำ เพราะ Leap Year และวันเกิดยังไม่ถึงในปีนี้

Query: หาคนอายุ 18-65 ปี (Working Age)

SELECT * FROM DemoTable611
WHERE TIMESTAMPDIFF(YEAR, DOB, CURDATE()) BETWEEN 18 AND 65;

ตัวอย่างเพิ่มเติม: อายุครบรอบวันเกิดปีนี้

SELECT 
    DOB,
    CASE 
        WHEN DATE_FORMAT(DOB, '%m-%d') > DATE_FORMAT(CURDATE(), '%m-%d') 
        THEN YEAR(CURDATE()) - YEAR(DOB) - 1
        ELSE YEAR(CURDATE()) - YEAR(DOB)
    END AS age_exact
FROM DemoTable611;

สรุป Best Practice

  1. ใช้ TIMESTAMPDIFF(YEAR, DOB, CURDATE()) - ถูกต้อง เร็ว อ่านง่าย
  2. อย่าใช้ DATEDIFF/365.25 - ผิดพลาดได้
  3. ถ้าต้อง Query บ่อย ให้เพิ่ม Generated Column + Index:
    ALTER TABLE users 
    ADD COLUMN age_years INT GENERATED ALWAYS AS 
        (TIMESTAMPDIFF(YEAR, dob, CURDATE())) STORED,
    ADD INDEX idx_age (age_years);
  4. สำหรับ Birthday Reminder (วันเกิดใน 7 วันข้างหน้า):
    SELECT * FROM users
    WHERE DATE_FORMAT(dob, '%m-%d') 
    BETWEEN DATE_FORMAT(CURDATE(), '%m-%d') 
    AND DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 7 DAY), '%m-%d');