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

Dùng FIND_IN_SET() cho đối số phân cách bằng dấu phẩy trong MySQL

Vấn đề

Toán tử IN không hoạt động trực tiếp với chuỗi phân cách bằng dấu phẩy (CSV) trong một cột hoặc biến.

Giải pháp: FIND_IN_SET()

Cú pháp: FIND_IN_SET(str, csv_string) - trả về vị trí (1-based) của str trong csv_string, trả về 0 nếu không tìm thấy.

Ví dụ

Tạo bảng:

CREATE TABLE DemoTable604 (
    Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    Title VARCHAR(100)
);
INSERT INTO DemoTable604(Title) VALUES
('MySQL'), ('C++'), ('MongoDB'), ('Java');

Truy vấn tìm Title trong danh sách 'C++,MongoDB':

SELECT * FROM DemoTable604
WHERE FIND_IN_SET(Title, 'C++,MongoDB');

Kết quả:

+----+---------+
| Id | Title   |
+----+---------+
| 2  | C++     |
| 3  | MongoDB |
+----+---------+

So sánh IN vs FIND_IN_SET

Đặc điểmIN (value1, value2...)FIND_IN_SET(col, 'csv')
Đối sốDanh sách giá trị rời rạc1 chuỗi CSV
Sử dụng indexCó (nếu cột có index)Không (full scan)
Ký tự đặc biệt trong giá trịDễ dàng (quote riêng)Khó (dấu phẩy trong giá trị gây lỗi)
Hiệu năngTốtKém (function trên cột)

Khi nào dùng FIND_IN_SET

  • Dữ liệu lưu dưới dạng CSV trong 1 cột (bad design nhưng phổ biến legacy).
  • Tham số truyền vào từ ứng dụng dạng CSV string.
  • Bảng nhỏ, không quan tâm index.

Thiết kế tốt hơn

Thay vì lưu CSV, hãy dùng bảng liên kết (many-to-many):

CREATE TABLE items (id INT PRIMARY KEY, name VARCHAR(100));
CREATE TABLE tags (id INT PRIMARY KEY, name VARCHAR(100));
CREATE TABLE item_tags (item_id INT, tag_id INT, PRIMARY KEY(item_id, tag_id));

Truy vấn: SELECT i.* FROM items i JOIN item_tags it ON i.id=it.item_id WHERE it.tag_id IN (1,2,3).