Vấn đề
Cột VARCHAR lưu số ('190', '230'...). MIN()/MAX() trên VARCHAR so sánh theo thứ tự từ điển (lexicographic): '190' > '230' vì '1' < '2'. Cần CAST sang số.
Ví dụ minh họa
Tạo bảng và chèn dữ liệu
mysql> CREATE TABLE DemoTable (Value VARCHAR(100));
mysql> INSERT INTO DemoTable VALUES ('190'), ('230'), ('120'), ('189');
Sai: MIN/MAX trực tiếp trên VARCHAR
SELECT MIN(Value), MAX(Value) FROM DemoTable;
+-----------+-----------+ | MIN(Value) | MAX(Value) | +-----------+-----------+ | 120 | 230 | -- Ngẫu nhiên đúng do dữ liệu này +-----------+-----------+
Thử thêm '99' → MAX = '99' (sai, vì '9' > '2').
Đúng: CAST sang SIGNED/UNSIGNED
mysql> SELECT
MIN(CAST(Value AS SIGNED)) AS Min,
MAX(CAST(Value AS SIGNED)) AS Max
FROM DemoTable;
Kết quả
+------+------+ | Min | Max | +------+------+ | 120 | 230 | +------+------+
Các kiểu CAST số
| Kiểu | Phạm vi | Dùng cho |
|---|---|---|
| SIGNED | -2^63 ~ 2^63-1 | Số có dấu (mặc định) |
| UNSIGNED | 0 ~ 2^64-1 | Số không âm (ID, count...) |
| DECIMAL(p,s) | Tùy precision | Số thập phân chính xác |
Lưu ý
- Giá trị không phải số (abc) → CAST thành 0 (với warning).
- Nên dùng
NULLIF(TRIM(Value), '')trước CAST để tránh chuỗi rỗng thành 0. - Tốt nhất: **Lưu số bằng kiểu số (INT, DECIMAL)** từ đầu.