MySQL **ไม่มีชนิดข้อมูล** สำหรับเก็บ "เดือนและปี" อย่างเดียว (No MONTH_YEAR type) แนวทางปฏิบัติที่ดีคือ **เก็บเป็น DATE หรือ DATETIME แล้วดึงส่วนที่ต้องการตอน Query**
ทำไมไม่ควรเก็บแยกเดือน/ปี
- ไม่สามารถคำนวณช่วงเวลาได้ง่าย (เช่น "3 เดือนที่แล้ว")
- ไม่มี Index ที่ทำงานได้ดีสำหรับ Range Query
- Validation ซับซ้อน (เดือน 1-12, ปี 4 หลัก)
- Sorting ผิดปกติ (เดือน 10, 11, 12 จะอยู่ก่อน 1, 2, 3)
แนวทางแนะนำ: ใช้ DATE/DATETIME
1. สร้างตาราง
mysql> CREATE TABLE OnlyMonthandYear (
-> DueDateTime DATETIME
-> );
Query OK, 0 rows affected (0.56 sec)
2. เพิ่มข้อมูล (วันที่วันแรกของเดือนแทนเดือนนั้น)
mysql> INSERT INTO OnlyMonthandYear VALUES ('2016-12-10');
mysql> INSERT INTO OnlyMonthandYear VALUES ('2017-10-21');
mysql> INSERT INTO OnlyMonthandYear VALUES ('2018-03-25');
mysql> INSERT INTO OnlyMonthandYear VALUES ('2018-12-18');
3. ดึงเดือนและปี
mysql> SELECT MONTH(DueDateTime) AS OnlyMonth, YEAR(DueDateTime) AS OnlyYear
-> FROM OnlyMonthandYear;
+-----------+----------+
| OnlyMonth | OnlyYear |
+-----------+----------+
| 12 | 2016 |
| 10 | 2017 |
| 3 | 2018 |
| 12 | 2018 |
+-----------+----------+
4 rows in set (0.02 sec)
ฟังก์ชันดึงส่วนประกอบวันที่
| ฟังก์ชัน | คืนค่า | ตัวอย่าง |
|---|---|---|
YEAR(date) | ปี (1000-9999) | 2018 |
MONTH(date) | เดือน (1-12) | 11 |
DAY(date) | วันที่ (1-31) | 26 |
QUARTER(date) | ไตรมาส (1-4) | 4 |
WEEK(date, mode) | สัปดาห์ในปี | 47 |
DAYOFWEEK(date) | วันในสัปดาห์ (1=Sun) | 2 |
DAYOFYEAR(date) | วันในปี (1-366) | 330 |
EXTRACT(unit FROM date) | ดึงตามหน่วยที่ระบุ | EXTRACT(MONTH FROM dt) |
EXTRACT() - มาตรฐาน ANSI SQL
SELECT EXTRACT(YEAR_MONTH FROM DueDateTime) AS YearMonth FROM OnlyMonthandYear;
+-----------+
| YearMonth |
+-----------+
| 201612 |
| 201710 |
| 201803 |
| 201812 |
+-----------+
4 rows in set (0.00 sec)
Query ช่วงเดือน (Range Query) - ใช้ Index ได้
-- เดือนตุลาคม 2018
SELECT * FROM OnlyMonthandYear
WHERE DueDateTime >= '2018-10-01' AND DueDateTime < '2018-11-01';
-- 3 เดือนล่าสุด
SELECT * FROM OnlyMonthandYear
WHERE DueDateTime >= DATE_SUB((SELECT MAX(DueDateTime) FROM OnlyMonthandYear), INTERVAL 3 MONTH);
รูปแบบแสดงผลสำหรับ UI/Report
SELECT
DATE_FORMAT(DueDateTime, '%m/%Y') AS MM_YYYY, -- 12/2016
DATE_FORMAT(DueDateTime, '%M %Y') AS Month_Year, -- December 2016
DATE_FORMAT(DueDateTime, '%Y-%m') AS YYYY_MM -- 2016-12 (Sortable)
FROM OnlyMonthandYear;
สรุป
✅ **ทำ:** เก็บ DATE (วันแรกของเดือน) → ใช้ MONTH(), YEAR(), DATE_FORMAT(), EXTRACT()
❌ **ไม่ทำ:** เก็บ VARCHAR('11/2018') หรือคอลัมน์แยก month INT, year INT