Vấn đề
Cột lưu danh sách giá trị phân cách bằng dấu chấm phẩy: '100;200;300'. Cần tìm dòng chứa giá trị '8'.
Giải pháp: REPLACE + FIND_IN_SET
FIND_IN_SET chỉ làm việc với dấu phẩy. Đổi ';' thành ',' trước.
SELECT * FROM DemoTable
WHERE FIND_IN_SET('8', REPLACE(Value, ';', ',')) > 0;
Ví dụ minh họa
Tạo bảng và chèn dữ liệu
mysql> CREATE TABLE DemoTable (
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Value VARCHAR(100)
);
mysql> INSERT INTO DemoTable (Value) VALUES
('100;200;300'), ('1;300;400'), ('6;7;8;9;10'), ('1;2;3;4;5'), ('3;8;9;10');
Truy vấn tìm giá trị 8
mysql> SELECT * FROM DemoTable WHERE FIND_IN_SET(8, REPLACE(Value, ';', ',')) > 0;
Kết quả
+----+------------+ | Id | Value | +----+------------+ | 3 | 6;7;8;9;10 | | 5 | 3;8;9;10 | +----+------------+
Giải thích
REPLACE(Value, ';', ','): '6;7;8;9;10' → '6,7,8,9,10'.FIND_IN_SET('8', ...): Tìm '8' trong chuỗi CSV → trả về vị trí > 0.> 0: Điều kiện TRUE (tìm thấy).
⚠️ Hạn chế
- Không dùng index → Full table scan.
- Giá trị chứa dấu phẩy/chấm phẩy bên trong sẽ bị hiểu nhầm.
- Chuỗi rỗng, NULL cần xử lý riêng.
Thiết kế tốt hơn: Chuẩn hóa (Normalization)
CREATE TABLE items (id INT PRIMARY KEY); CREATE TABLE item_values (item_id INT, value INT, PRIMARY KEY(item_id, value));
Sau đó: SELECT i.* FROM items i JOIN item_values v ON i.id=v.item_id WHERE v.value=8; (có index, nhanh, chuẩn).
MySQL 8.0: JSON
-- Lưu: ['100','200','300'] WHERE JSON_CONTAINS(values_json, '8');