Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Cập nhật chỉ tháng (MONTH) của cột DATE trong MySQL

Giới thiệu

Để thay đổi tháng của cột DATE mà giữ nguyên năm và ngày, dùng DATE_ADD() với INTERVAL ... MONTH kết hợp điều kiện WHERE MONTH(date) = ....

Ví dụ thực hành

1. Tạo bảng DemoTable861

mysql> CREATE TABLE DemoTable861 (AdmissionDate DATE);

2. Chèn dữ liệu (cùng tháng 01)

mysql> INSERT INTO DemoTable861 VALUES 
    ('2019-01-21'),('2018-01-01'),('2016-01-02'),('2018-01-14');

3. Trừ 1 tháng cho các hàng tháng 01

mysql> UPDATE DemoTable861 
    SET AdmissionDate = DATE_ADD(AdmissionDate, INTERVAL -1 MONTH)
    WHERE MONTH(AdmissionDate) = 1;

4. Kết quả (tháng 01 → tháng 12 năm trước)

+---------------+
| AdmissionDate |
+---------------+
| 2018-12-21    |
| 2017-12-01    |
| 2015-12-02    |
| 2017-12-14    |
+---------------+

Các cách khác để thay đổi tháng

-- Cách 1: DATE_SUB (ngắn gọn hơn cho trừ)
UPDATE DemoTable861 SET AdmissionDate = DATE_SUB(AdmissionDate, INTERVAL 1 MONTH) WHERE MONTH(AdmissionDate) = 1;

-- Cách 2: Tái tạo ngày từ năm/ngày cũ + tháng mới (MySQL 8.0+)
UPDATE DemoTable861 
SET AdmissionDate = MAKEDATE(YEAR(AdmissionDate), 1) + INTERVAL (3-1) MONTH + INTERVAL DAY(AdmissionDate)-1 DAY
WHERE MONTH(AdmissionDate) = 1; -- đặt tháng = 3 (March)

-- Cách 3: Dùng DATE_FORMAT + STR_TO_DATE (linh hoạt nhưng chậm)
UPDATE DemoTable861 
SET AdmissionDate = STR_TO_DATE(CONCAT(YEAR(AdmissionDate), '-03-', LPAD(DAY(AdmissionDate),2,'0')), '%Y-%m-%d')
WHERE MONTH(AdmissionDate) = 1;

⚠️ Cảnh báo: Ngày vượt quá số ngày của tháng mới

-- 2019-01-31 - 1 MONTH = 2018-12-31 (OK)
-- 2019-03-31 - 1 MONTH = 2019-02-28 (MySQL tự điều chỉnh ngày cuối tháng)
-- 2019-01-31 + 1 MONTH = 2019-02-28 (không phải 2019-02-31)

MySQL tự động clamp ngày đến ngày cuối tháng đích. Điều này thường là hành vi mong muốn.

Lưu ý

  • MONTH(date) trả về 1-12.
  • Index trên AdmissionDate không dùng được cho WHERE MONTH(AdmissionDate)=1 (function trên cột). Cần generated column month_col = MONTH(AdmissionDate) + index nếu lọc thường xuyên.