ฟังก์ชัน FIND_IN_SET()
FIND_IN_SET(needle, haystack)
needle: ค่าที่ต้องการค้นหา (String)
haystack: สตริง CSV (Comma-Separated)
- คืนค่า: ตำแหน่ง 1-based (1,2,3...) หรือ 0 ถ้าไม่พบ
ตัวอย่าง: ตาราง demo73
CREATE TABLE demo73 (
interest_id VARCHAR(100),
interest_name VARCHAR(100)
);
INSERT INTO demo73 VALUES
('100,101,103,105', 'SSC'),
('105,103,1005,1003,104', 'Computer'),
('110,105,104,111', 'Novel');
ข้อมูล
+-----------------------+---------------+
| interest_id | interest_name |
+-----------------------+---------------+
| 100,101,103,105 | SSC |
| 105,103,1005,1003,104 | Computer |
| 110,105,104,111 | Novel |
+-----------------------+---------------+
คำสั่ง: หา Interest ที่มี 103
SELECT * FROM demo73
WHERE FIND_IN_SET('103', interest_id) > 0;
ผลลัพธ์ (2 แถว)
+-----------------------+---------------+
| interest_id | interest_name |
+-----------------------+---------------+
| 100,101,103,105 | SSC |
| 105,103,1005,1003,104 | Computer |
+-----------------------+---------------+
จุดสำคัญ
- ค้นหา '103' → เจอใน '100,101,103,105' และ '105,103,1005...'
- ไม่ เจอใน '1005' หรือ '1003' เพราะ FIND_IN_SET จับคู่ ทั้งค่า (Exact match per element)
- ต่างจาก LIKE '%103%' ที่จะเจอ 1003, 1005 ด้วย (False Positive)
ข้อจำกัด
| ข้อจำกัด | รายละเอียด |
| Delimiter | Comma (,) เท่านั้น — ไม่รองรับ ; | tab อื่นๆ |
| Space | '100, 101' จะไม่ match '101' (ต้อง '100,101') |
| NULL | FIND_IN_SET('103', NULL) → NULL (ไม่ใช่ 0) |
| Index | ไม่ใช้ INDEX ได้ → Full Table Scan |
| Length | haystack ต้อง ≤ 512 bytes (เก่า) / 64KB (ใหม่) |
กรณีมี Space: ใช้ REPLACE ก่อน
WHERE FIND_IN_SET('103', REPLACE(interest_id, ', ', ',')) > 0;
แนวทางแทนที่ (Best Practice)
1. Normalized Table (แนะนำ)
CREATE TABLE interests (
id INT PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE entity_interests (
entity_id INT,
interest_id INT,
PRIMARY KEY (entity_id, interest_id),
FOREIGN KEY (interest_id) REFERENCES interests(id)
);
2. JSON Column (MySQL 5.7+)
ALTER TABLE demo73 ADD interests JSON;
UPDATE demo73 SET interests = JSON_ARRAY(100,101,103,105) WHERE interest_name = 'SSC';
SELECT * FROM demo73 WHERE JSON_CONTAINS(interests, '103');
3. Generated Column + Index (MySQL 5.7+)
ALTER TABLE demo73
ADD COLUMN has_103 BOOLEAN AS (FIND_IN_SET('103', interest_id) > 0) STORED,
ADD INDEX idx_has_103 (has_103);