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

Truy vấn MySQL lấy giá trị max từ cột VARCHAR chứa số?

Tìm giá trị MAX từ cột VARCHAR chứa số trong MySQL

Cột VARCHAR so sánh theo thứ tự từ điển (lexicographic), '9' > '1000'. Cần CAST(... AS UNSIGNED) để so sánh theo giá trị số.

Ví dụ

Tạo bảng:

mysql> CREATE TABLE findMaxValueInVarcharField (
    -> Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> Value VARCHAR(200)
    -> );

Chèn dữ liệu:

mysql> INSERT INTO findMaxValueInVarcharField(Value) VALUES
('200'), ('1000'), ('899474'), ('39474'), ('4958');

Dữ liệu:

+----+--------+
| Id | Value  |
+----+--------+
| 1  | 200    |
| 2  | 1000   |
| 3  | 899474 |
| 4  | 39474  |
| 5  | 4958   |
+----+--------+

Tìm MAX theo giá trị số:

mysql> SELECT MAX(CAST(Value AS UNSIGNED)) AS MaximumValueFromVarcharField 
FROM findMaxValueInVarcharField;

Kết quả:

+------------------------------+
| MaximumValueFromVarcharField |
+------------------------------+
| 899474                       |
+------------------------------+

So sánh không CAST (sai)

mysql> SELECT MAX(Value) FROM findMaxValueInVarcharField;
+-----------+
| MAX(Value) |
+-----------+
| 999999    |  -- Sai! So sánh chuỗi: '9' > '1' > '8'...
+-----------+

Các kiểu CAST cho số

  • CAST(col AS UNSIGNED): Số nguyên không dấu (0 đến 2^64-1)
  • CAST(col AS SIGNED): Số nguyên có dấu (-2^63 đến 2^63-1)
  • CAST(col AS DECIMAL(20,2)): Số thập phân cố định

Tối ưu hóa cho bảng lớn

  1. Generated Column (MySQL 5.7+):
    ALTER TABLE t ADD value_num BIGINT AS (CAST(Value AS UNSIGNED)) STORED;
    CREATE INDEX idx_value_num ON t(value_num);
    SELECT MAX(value_num) FROM t;
  2. Functional Index (MySQL 8.0.13+):
    CREATE INDEX idx_value_cast ON t((CAST(Value AS UNSIGNED)));
  3. Đổi kiểu cột: ALTER TABLE ... MODIFY Value BIGINT (nếu dữ liệu cho phép)

Lưu ý

  • CAST trong WHERE/ORDER BY/GROUP BY làm mất index trên cột VARCHAR gốc
  • Giá trị không phải số (abc) → CAST thành 0
  • NULL → CAST thành NULL