ฟังก์ชัน FIND_IN_SET() ใน MySQL ใช้ค้นหาสตริงในรายการที่คั่นด้วยจุลภาค (Comma-Separated List) คืนค่าตำแหน่ง (1-based index) หากเจอ หรือ 0 หากไม่เจอ เหมาะสำหรับคอลัมน์ที่เก็บหลายค่าในรูปแบบ CSV
ไวยากรณ์
FIND_IN_SET(str, strlist)
- str: สตริงที่ต้องการค้นหา
- strlist: สตริงรายการคั่นด้วยจุลภาค (เช่น 'A,B,C')
ตัวอย่างการใช้งาน
สร้างตารางรหัสประเทศ:
mysql> CREATE TABLE DemoTable1439 (
-> CountryId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> CountryCode VARCHAR(20)
-> );
เพิ่มข้อมูล (หลายรหัสในคอลัมน์เดียว):
mysql> INSERT INTO DemoTable1439 (CountryCode) VALUES ('1022_US,7894_UK');
mysql> INSERT INTO DemoTable1439 (CountryCode) VALUES ('6567_AUS,7894_UK');
mysql> INSERT INTO DemoTable1439 (CountryCode) VALUES ('6567_AUS');
ดูข้อมูล:
mysql> SELECT * FROM DemoTable1439; +-----------+------------------+ | CountryId | CountryCode | +-----------+------------------+ | 1 | 1022_US,7894_UK | | 2 | 6567_AUS,7894_UK | | 3 | 6567_AUS | +-----------+------------------+
ค้นหาระเบียนที่มี '6567_AUS':
mysql> SELECT * FROM DemoTable1439
-> WHERE FIND_IN_SET('6567_AUS', CountryCode) > 0;
ผลลัพธ์ (เจอแถวที่ 2 และ 3):
+-----------+------------------+ | CountryId | CountryCode | +-----------+------------------+ | 2 | 6567_AUS,7894_UK | | 3 | 6567_AUS | +-----------+------------------+
ข้อควรระวัง
- Case-sensitive: 'abc' และ 'ABC' ถือว่าต่างกัน
- ไม่รองรับช่องว่าง: 'A, B, C' จะไม่เจอ 'B' (ต้องเป็น 'A,B,C')
- ไม่สามารถใช้ Index ได้: Full Table Scan ทุกครั้ง
- คืนค่า 0 หาก strlist เป็น NULL
วิธีทางเลือกที่ดีกว่า (Best Practice)
- Normalization: สร้างตารางแยก CountryCodes (CountryId, Code) - แนะนำมากที่สุด
- JSON Data Type (MySQL 5.7+): ใช้
JSON_CONTAINS()หรือJSON_SEARCH()พร้อม Index - SET Data Type:
CREATE TABLE t (codes SET('US','UK','AUS'))- จำกัดค่าที่กำหนดไว้ล่วงหน้า
กรณีที่ยอมรับ FIND_IN_SET ได้
- ตารางเล็ก (< 1000 แถว)
- ข้อมูลอ่านอย่างเดียว (Read-heavy, Rarely updated)
- โครงสร้างเดิมที่ยากต่อการเปลี่ยน (Legacy system)
- Prototyping / Proof of Concept