Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

การตรวจสอบรหัสประเทศในคอลัมน์ CSV ด้วย FIND_IN_SET ใน MySQL

ฟังก์ชัน 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)

  1. Normalization: สร้างตารางแยก CountryCodes (CountryId, Code) - แนะนำมากที่สุด
  2. JSON Data Type (MySQL 5.7+): ใช้ JSON_CONTAINS() หรือ JSON_SEARCH() พร้อม Index
  3. 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