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

SELECT không phân biệt chữ hoa/thường với IN() trong MySQL dùng UPPER()

Mặc định MySQL so sánh chuỗi không phân biệt chữ hoa/thường (case-insensitive) với collation mặc định (ví dụ: utf8mb4_general_ci, latin1_swedish_ci — hậu tố _ci = case insensitive). Tuy nhiên, để đảm bảo rõ ràng, độc lập collation, hoặc khi collation là _cs (case sensitive), hãy dùng UPPER() hoặc LOWER() cho cả cột và giá trị trong IN().

Ví dụ minh họa

Tạo bảng:

mysql> CREATE TABLE DemoTable1460 (
    Name VARCHAR(20)
);

Chèn dữ liệu:

mysql> INSERT INTO DemoTable1460 VALUES ('Chris');
mysql> INSERT INTO DemoTable1460 VALUES ('David');
mysql> INSERT INTO DemoTable1460 VALUES ('Bob');
mysql> INSERT INTO DemoTable1460 VALUES ('Robert');

Dữ liệu:

mysql> SELECT * FROM DemoTable1460;
+--------+
| Name   |
+--------+
| Chris  |
| David  |
| Bob    |
| Robert |
+--------+

Truy vấn case-insensitive với IN()

mysql> SELECT * FROM DemoTable1460 
    WHERE UPPER(Name) IN ('CHRIS', 'BOB');

Kết quả (khớp 'Chris' và 'Bob' bất kể case):

+-------+
| Name  |
+-------+
| Chris |
| Bob   |
+-------+

Các cách đạt được case-insensitive

CáchCú phápƯu/nhược điểm
UPPER(col) IN (UPPER(val1), ...)Chuẩn, rõ ràng, hoạt động mọi collationGọi hàm trên cột → mất index
LOWER(col) IN (LOWER(val1), ...)Tương tự UPPERMất index
Collation _ciWHERE Name COLLATE utf8mb4_general_ci IN ('chris', 'bob')Có thể dùng index nếu collation khớp
Mặc định (nếu collation _ci)WHERE Name IN ('chris', 'bob')Đơn giản nhất, dùng index

⚠️ Hiệu năng & Index

  • UPPER(Name) làm mất index trên cột Name (function trên cột).
  • Nếu hiệu năng quan trọng: Đảm bảo cột dùng collation _ci và viết giá trị IN() theo case bất kỳ — MySQL sẽ so sánh case-insensitive tự nhiên và vẫn dùng index.
  • MySQL 8.0+: Tạo functional index trên UPPER(Name) nếu buộc phải dùng hàm.

Kiểm tra collation hiện tại

SHOW TABLE STATUS LIKE 'DemoTable1460';
-- Collation: utf8mb4_general_ci (ci = case insensitive)

SHOW FULL COLUMNS FROM DemoTable1460;
-- Collation của từng cột

Best Practice

  1. Thiết kế schema với collation utf8mb4_general_ci hoặc utf8mb4_0900_ai_ci (mặc định MySQL 8.0) — case-insensitive tự nhiên.
  2. Viết query đơn giản: WHERE Name IN ('chris', 'bob') — tận dụng index.
  3. Chỉ dùng UPPER()/LOWER() khi: collation là _cs, hoặc cần logic case-insensitive trên cột _cs, hoặc so sánh cross-collation.