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

เก็บเดือนและปีใน MySQL: ใช้ DATETIME แล้ว EXTRACT ด้วย MONTH() และ YEAR()

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