Hàm DATE_FORMAT() trả về NULL nếu đầu vào là NULL. Tuy nhiên, để rõ ràng và kiểm soát, dùng IF() hoặc COALESCE().
Cú pháp
SELECT IF(cột_ngày, DATE_FORMAT(cột_ngày, 'định_dạng'), NULL) FROM tên_bảng;
Ví dụ minh họa
Tạo bảng có cột DATETIME cho phép NULL:
mysql> CREATE TABLE returnNullWhenInputIsNullDemo (
-> Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> ShippingDate DATETIME
-> );
Query OK, 0 rows affected (1.21 sec)
Chèn dữ liệu (có NULL):
mysql> INSERT INTO returnNullWhenInputIsNullDemo(ShippingDate) VALUES
-> ('2019-01-21'), (NULL), ('2018-03-25'), (NULL), (NULL),
-> ('2012-04-23'), ('2018-12-01'), ('2016-11-13');
Xem dữ liệu gốc:
mysql> SELECT * FROM returnNullWhenInputIsNullDemo;
+----+---------------------+ | Id | ShippingDate | +----+---------------------+ | 1 | 2019-01-21 00:00:00 | | 2 | NULL | | 3 | 2018-03-25 00:00:00 | | 4 | NULL | | 5 | NULL | | 6 | 2012-04-23 00:00:00 | | 7 | 2018-12-01 00:00:00 | | 8 | 2016-11-13 00:00:00 | +----+---------------------+
Format ngày, giữ NULL cho hàng NULL:
mysql> SELECT IF(ShippingDate, DATE_FORMAT(ShippingDate, '%d/%m/%Y'), NULL)
-> FROM returnNullWhenInputIsNullDemo;
+-------------------------------------------------------------+ | IF(ShippingDate, DATE_FORMAT(ShippingDate, '%d/%m/%Y'), NULL) | +-------------------------------------------------------------+ | 21/01/2019 | | NULL | | 25/03/2018 | | NULL | | NULL | | 23/04/2012 | | 01/12/2018 | | 13/11/2016 | +-------------------------------------------------------------+
Các cách viết tương đương
| Cách viết | Cú pháp | Ghi chú |
|---|---|---|
| IF() | IF(date_col, DATE_FORMAT(...), NULL) | Rõ ràng, dễ hiểu |
| CASE | CASE WHEN date_col IS NOT NULL THEN DATE_FORMAT(...) END | Chuẩn SQL, nhiều nhánh |
| COALESCE | COALESCE(DATE_FORMAT(date_col, ...), NULL) | DATE_FORMAT(NULL) đã trả NULL, COALESCE thừa |
| NULLIF | NULLIF(DATE_FORMAT(date_col, ...), '') | Nếu format trả rỗng thì thành NULL |
Tại sao cần xử lý NULL tường minh?
- Tránh lỗi logic downstream (ứng dụng nhận chuỗi rỗng thay vì NULL)
- Rõ ràng ý định code cho maintainer
- Tuân thủ coding standard của team
- Dễ debug: thấy NULL rõ ràng trong kết quả
Ứng dụng: Format nhiều cột ngày cùng lúc
SELECT
IF(created_at, DATE_FORMAT(created_at, '%d/%m/%Y'), NULL) AS created,
IF(updated_at, DATE_FORMAT(updated_at, '%d/%m/%Y'), NULL) AS updated,
IF(deleted_at, DATE_FORMAT(deleted_at, '%d/%m/%Y'), NULL) AS deleted
FROM posts;