Khi cột lưu số dưới dạng chuỗi (VARCHAR/CHAR), so sánh trực tiếp sẽ so sánh theo thứ tự chữ (lexicographic), không phải giá trị số. Dùng CAST() để chuyển sang kiểu số.
Cú pháp
SELECT * FROM tên_bảng WHERE CAST(tên_cột AS SIGNED) = giá_trị_số;
Ví dụ minh họa
Tạo bảng lưu ID dạng chuỗi:
mysql> CREATE TABLE compareTwoStringDemo (
-> UserId VARCHAR(100)
-> );
Query OK, 0 rows affected (0.78 sec)
Chèn dữ liệu:
mysql> INSERT INTO compareTwoStringDemo VALUES
-> ('1083745'), ('9867585'), ('3547483'), ('9845646'), ('9876532');
Xem dữ liệu:
mysql> SELECT * FROM compareTwoStringDemo;
+---------+ | UserId | +---------+ | 1083745 | | 9867585 | | 3547483 | | 9845646 | | 9876532 | +---------+
So sánh chính xác giá trị số 3547483:
mysql> SELECT * FROM compareTwoStringDemo
-> WHERE CAST(UserId AS SIGNED) = 3547483;
+---------+ | UserId | +---------+ | 3547483 | +---------+
Tại sao cần CAST?
Nếu so sánh chuỗi trực tiếp:
SELECT * FROM compareTwoStringDemo WHERE UserId = '3547483'; -- OK (so sánh chuỗi) SELECT * FROM compareTwoStringDemo WHERE UserId = 3547483; -- MySQL tự CAST ngầm, nhưng không chắc chắn
Vấn đề nảy sinh khi so sánh phạm vi:
-- So sánh chuỗi: '9' > '1000000' (vì '9' > '1' theo thứ tự chữ) SELECT * FROM compareTwoStringDemo WHERE UserId > '1000000'; -- Sai! -- So sánh số: 9 < 1000000 (đúng) SELECT * FROM compareTwoStringDemo WHERE CAST(UserId AS SIGNED) > 1000000; -- Đúng!
Các kiểu CAST hỗ trợ
| Kiểu | Mô tả |
|---|---|
| SIGNED | Số nguyên có dấu (INT) |
| UNSIGNED | Số nguyên không dấu |
| DECIMAL(M,D) | Số thập phân chính xác |
| CHAR(N) | Chuỗi độ dài cố định |
| DATE/DATETIME/TIME | Ngày giờ |