Để chuyển đổi cột kiểu chuỗi (VARCHAR, TEXT) sang kiểu số thực (DECIMAL, DOUBLE) trong MySQL, bạn dùng hàm CAST() hoặc CONVERT().
Cú pháp
-- CAST (chuẩn ANSI SQL)
SELECT CAST(ten_cot AS DECIMAL(10,2)) AS ten_moi FROM ten_bang;
-- CONVERT (MySQL specific)
SELECT CONVERT(ten_cot, DECIMAL(10,2)) AS ten_moi FROM ten_bang;
Tham số DECIMAL(10,2) nghĩa là: tổng 10 chữ số, trong đó 2 chữ số sau dấu phẩy.
Ví dụ minh họa
1. Tạo bảng
CREATE TABLE VarcharToDouble (
Id INT NOT NULL AUTO_INCREMENT,
Name VARCHAR(10),
Amount VARCHAR(10),
PRIMARY KEY(Id)
);
2. Chèn dữ liệu (số lưu dưới dạng chuỗi)
INSERT INTO VarcharToDouble(Name, Amount) VALUES
('John', '456.78'),
('Larry', '8465.98'),
('Mike', '9083.45'),
('Sam', '46475.50'),
('Carol', '10003.35');
3. Xem dữ liệu gốc
SELECT * FROM VarcharToDouble;
Kết quả: Cột Amount là VARCHAR.
4. Chuyển đổi và sắp xếp
SELECT Id, Name,
CAST(Amount AS DECIMAL(10,2)) AS TotalAmount
FROM VarcharToDouble
ORDER BY TotalAmount DESC;
Kết quả (đã sắp xếp số đúng):
+----+-------+-------------+
| Id | Name | TotalAmount |
+----+-------+-------------+
| 4 | Sam | 46475.50 |
| 5 | Carol | 10003.35 |
| 3 | Mike | 9083.45 |
| 2 | Larry | 8465.98 |
| 1 | John | 456.78 |
+----+-------------+
⚠️ Xử lý dữ liệu "bẩn" (chứa ký tự không phải số)
Vấn đề: Dữ liệu có dấu phẩy, ký tự tiền tệ, khoảng trắng
-- Dữ liệu: '1,234.56', '$100.00', ' 500 ', 'abc'
-- CAST trực tiếp sẽ trả về 0 hoặc NULL tùy phiên bản
Giải pháp: Làm sạch trước khi CAST
SELECT CAST(
REPLACE(REPLACE(REPLACE(TRIM(Amount), ',', ''), '$', ''), ' ', '')
AS DECIMAL(15,2)
) AS CleanAmount FROM bang;
MySQL 8.0+: REGEXP_REPLACE (nếu bật)
SELECT CAST(
REGEXP_REPLACE(TRIM(Amount), '[^0-9.]', '')
AS DECIMAL(15,2)
) AS CleanAmount FROM bang;
So sánh kiểu số thực
| Kiểu | Độ chính xác | Khoảng giá trị | Dung lượng |
|---|---|---|---|
DECIMAL(M,D) | Chính xác (fixed-point) | Tùy M,D | ~M/2 bytes |
DOUBLE | Gần đúng (floating-point) | ±1.7E308 | 8 bytes |
FLOAT | Gần đúng | ±3.4E38 | 4 bytes |
Khuyến nghị
- Tiền tệ, tài chính: Luôn dùng
DECIMAL(19,4)hoặcDECIMAL(10,2) - Khoa học, đo lường:
DOUBLEhoặcFLOAT - CAST sang DECIMAL an toàn hơn DOUBLE cho tiền tệ
- Kiểm tra dữ liệu trước:
SELECT Amount, Amount REGEXP '^[0-9,.]+$' FROM bang;
Lưu ý ORDER BY
Nếu ORDER BY cột VARCHAR chứa số: '100' < '20' (so sánh chuỗi).
Sau CAST: 100 > 20 (so sánh số) → **Luôn CAST trước khi ORDER BY**.