บทนำ
เมื่อเก็บค่าหลายค่าในคอลัมน์เดียวคั่นด้วยคอมมา (Comma-separated Values) ไม่ควรใช้ IN() (ซึ่งทำงานกับชุดค่า ไม่ใช่สตริง) ควรใช้ FIND_IN_SET() แทน
ตัวอย่างการสร้างตารางและเพิ่มข้อมูล
mysql> CREATE TABLE DemoTable (
-> ListOfValues TEXT
-> );
Query OK, 0 rows affected (0.56 sec)
mysql> INSERT INTO DemoTable VALUES('10|20|30|40|50|60|100');
หมายเหตุ: ตัวอย่างใช้ | เป็น Delimiter ต้องแปลงเป็นคอมมาก่อน
แสดงข้อมูลทั้งหมด
mysql> SELECT * FROM DemoTable;
ผลลัพธ์
+-----------------------+
| ListOfValues |
+-----------------------+
| 10|20|30|40|50|60|100 |
+-----------------------+
1 row in set (0.00 sec)
คำสั่งค้นหา 100 ในรายการ (แปลง | เป็น , ก่อน)
mysql> SELECT FIND_IN_SET(100, REPLACE(ListOfValues, '|', ',')) FROM DemoTable;
ผลลัพธ์
+-------------------------------------------------+
| FIND_IN_SET(100, REPLACE(ListOfValues, '|', ',')) |
+-------------------------------------------------+
| 7 |
+-------------------------------------------------+
1 row in set (0.04 sec)
คำอธิบาย FIND_IN_SET
FIND_IN_SET(str, strlist)
str- ค่าที่ต้องการค้นหา (จะถูกแปลงเป็น String)strlist- สตริงที่มีค่าคั่นด้วยคอมมา (Comma-separated)- คืนค่า: ตำแหน่ง (1-based) หากเจอ, 0 หากไม่เจอ, NULL หากอาร์กิวเมนต์เป็น NULL
⚠️ ข้อจำกัดและข้อควรระวัง
- FIND_IN_SET ทำงานกับ Comma (,) เท่านั้น ต้อง REPLACE Delimiter อื่นเป็น Comma ก่อน
- ไม่สามารถใช้ Index ได้ (Full Table Scan)
- เหมาะกับข้อมูลเล็ก/คงที่ ไม่เหมาะกับข้อมูลเยอะหรือเปลี่ยนบ่อย
- การออกแบบที่ดีกว่า: ใช้ Junction Table (Many-to-Many) แทน CSV ในคอลัมน์
ตัวอย่างเพิ่มเติม
-- ข้อมูล: 'apple,banana,orange'
SELECT FIND_IN_SET('banana', 'apple,banana,orange'); -- 2
SELECT FIND_IN_SET('grape', 'apple,banana,orange'); -- 0
SELECT FIND_IN_SET('apple', NULL); -- NULL
-- ใช้ใน WHERE
SELECT * FROM Products
WHERE FIND_IN_SET('red', REPLACE(Tags, '|', ',')) > 0;