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

Có thể sắp xếp dữ liệu VARCHAR chứa cả chữ và số theo thứ tự tăng dần trong MySQL?

Sắp xếp VARCHAR chứa chữ và số theo thứ tự số học trong MySQL

Khi cột VARCHAR chứa cả số và chữ, sắp xếp mặc định (lexicographic) sẽ cho '100' < '190' < '20' < 'John'. Để sắp xếp số theo giá trị số học, dùng CAST() kết hợp IF() trong ORDER BY.

Ví dụ minh họa

Tạo bảng DemoTable:

mysql> CREATE TABLE DemoTable (EmployeeCode VARCHAR(100));
Query OK, 0 rows affected (1.17 sec)

Chèn dữ liệu:

mysql> INSERT INTO DemoTable VALUES('190');
Query OK, 1 row affected (0.14 sec)
mysql> INSERT INTO DemoTable VALUES('100');
Query OK, 1 row affected (0.30 sec)
mysql> INSERT INTO DemoTable VALUES('John');
Query OK, 1 row affected (0.23 sec)
mysql> INSERT INTO DemoTable VALUES('120');
Query OK, 1 row affected (0.21 sec)

Xem dữ liệu gốc:

mysql> SELECT * FROM DemoTable;
+--------------+
| EmployeeCode |
+--------------+
| 190          |
| 100          |
| John         |
| 120          |
+--------------+
4 rows in set (0.00 sec)

Sắp xếp: số trước (theo giá trị số), chữ sau:

mysql> SELECT * FROM DemoTable
ORDER BY IF(CAST(EmployeeCode AS SIGNED) = 0, 100000000000, CAST(EmployeeCode AS SIGNED));

Kết quả:

+--------------+
| EmployeeCode |
+--------------+
| 100          |
| 120          |
| 190          |
| John         |
+--------------+
4 rows in set, 1 warning (0.00 sec)

Giải thích logic

  • CAST(EmployeeCode AS SIGNED): Ép kiểu sang số nguyên. Với 'John' → trả về 0
  • IF(... = 0, 100000000000, ...): Nếu ép kiểu ra 0 (tức là không phải số) → gán giá trị rất lớn (đẩy xuống cuối)
  • Số hợp lệ giữ nguyên giá trị → được sắp xếp đúng thứ tự số học

Cách tiếp cận hiện đại hơn (MySQL 8.0+)

-- Sử dụng REGEXP để tách số và chữ
SELECT * FROM DemoTable
ORDER BY 
    CASE 
        WHEN EmployeeCode REGEXP '^[0-9]+$' THEN 0 ELSE 1 END,  -- Số trước, chữ sau
    CAST(EmployeeCode AS UNSIGNED);  -- Sắp xếp số học

Lưu ý

  • Cảnh báo (1 warning) xuất hiện do CAST('John' AS SIGNED) trả về 0 với warning "Truncated incorrect INTEGER value"
  • Cách dùng REGEXP sạch hơn và không gây warning
  • Nếu cần chữ trước, số sau: đổi thứ tự CASE (1 cho số, 0 cho chữ)