Giải pháp: MONTH(STR_TO_DATE())
Dùng STR_TO_DATE(str, '%b') parse tên tháng viết tắt thành DATE, sau đó MONTH() lấy số tháng.
Ví dụ minh họa
Tạo bảng
mysql> CREATE TABLE DemoTable (
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
MonthName VARCHAR(100)
);
mysql> INSERT INTO DemoTable(MonthName) VALUES('Jan'), ('Mar');
Dữ liệu gốc
+----+-----------+ | Id | MonthName | +----+-----------+ | 1 | Jan | | 2 | Mar | +----+-----------+
Truy vấn chuyển đổi
mysql> SELECT MONTH(STR_TO_DATE(MonthName, '%b')) FROM DemoTable;
Kết quả
+------------------------------------+ | MONTH(STR_TO_DATE(MonthName, '%b')) | +------------------------------------+ | 1 | | 3 | +------------------------------------+
Format specifier cho tháng
| Specifier | Định dạng | Ví dụ |
|---|---|---|
%b | Tên tháng viết tắt (3 chữ cái) | Jan, Feb, Mar |
%M | Tên tháng đầy đủ | January, February |
%m | Số tháng 2 chữ số | 01, 12 |
%c | Số tháng (1-2 chữ số) | 1, 12 |
Các ngôn ngữ (Locale)
Mặc định tiếng Anh. Đổi locale:
SET lc_time_names = 'vi_VN';
SELECT MONTH(STR_TO_DATE('Thg 1', '%b')); -- 1 (nếu locale hỗ trợ)
Xử lý case-insensitive
-- STR_TO_DATE đã case-insensitive cho %b/%M
SELECT MONTH(STR_TO_DATE('jan', '%b')); -- 1
SELECT MONTH(STR_TO_DATE('JAN', '%b')); -- 1
SELECT MONTH(STR_TO_DATE('Jan', '%b')); -- 1
Ứng dụng: Chuyển cột VARCHAR tháng sang INT
-- Thêm cột month_number ALTER TABLE DemoTable ADD month_num INT; -- Cập nhật UPDATE DemoTable SET month_num = MONTH(STR_TO_DATE(MonthName, '%b')); -- Tạo index cho month_num CREATE INDEX idx_month ON DemoTable(month_num);
Lưu ý
- Giá trị không parse được → trả về NULL
STR_TO_DATEtrả về DATE (ngày mặc định = 1, năm mặc định = 1970?)- Chỉ lấy MONTH() nên năm/ngày không quan trọng
- Hiệu năng: Không dùng index trên MonthName cho query này