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

จับคู่ค่ากับรายการคั่นจุลภาค (Comma-separated) ใน MySQL ด้วย FIND_IN_SET()

ปัญหา

คอลัมน์เก็บค่าหลายค่าคั่นด้วยจุลภาค (เช่น '23,45,78,56') ไม่สามารถใช้ IN() ได้โดยตรง เพราะ IN() คาดหวังรายการค่า ไม่ใช่สตริงเดียว

วิธีแก้: ใช้ FIND_IN_SET()

FIND_IN_SET(needle, haystack)
-- คืนค่า Position (1-based) ถ้าพบ, 0 ถ้าไม่พบ

ตัวอย่างสมบูรณ์

1. สร้างตารางและข้อมูล

CREATE TABLE DemoTable (`Values` VARCHAR(50));

INSERT INTO DemoTable VALUES ('23,45,78,56');
INSERT INTO DemoTable VALUES ('384,476,7456');
INSERT INTO DemoTable VALUES ('68,8,88,89');
INSERT INTO DemoTable VALUES ('78,80,84');

2. ค้นหาแถวที่มีค่า '8' ในรายการ

SELECT * FROM DemoTable 
WHERE FIND_IN_SET('8', `Values`) != 0;

3. ผลลัพธ์

+------------+
| Values     |
+------------+
| 68,8,88,89 |
+------------+

รายละเอียด FIND_IN_SET()

พารามิเตอร์คำอธิบาย
needleค่าที่ต้องการค้นหา (String)
haystackสตริงรายการคั่นจุลภาค (Comma-separated)
Returnตำแหน่ง (1,2,3...) หากพบ, 0 หากไม่พบ, NULL หากอาร์กิวเมนต์เป็น NULL

ข้อจำกัดและข้อควรระวัง

  • ไม่ใช้ Index → Full Table Scan เสมอ
  • คั่นต้องเป็น จุลภาค (,) เท่านั้น ไม่รองรับ Space, Semicolon, Pipe
  • ค่าที่มีจุลภาคภายใน (เช่น '1,2', '3,4') จะทำงานผิด
  • Case-sensitive ขึ้นกับ Collation ของคอลัมน์

แนวทางปฏิบัติที่ดีกว่า (Best Practice)

Normalize ข้อมูล: สร้างตารางความสัมพันธ์ (Many-to-Many)

CREATE TABLE Items (
    Id INT PRIMARY KEY,
    Name VARCHAR(50)
);

CREATE TABLE ItemTags (
    ItemId INT,
    Tag VARCHAR(50),
    PRIMARY KEY (ItemId, Tag),
    FOREIGN KEY (ItemId) REFERENCES Items(Id)
);

-- แทนที่จะเก็บ 'tag1,tag2,tag3' ในคอลัมน์เดียว

Query แบบ Normalized (เร็ว ใช้ Index ได้)

SELECT i.* FROM Items i
JOIN ItemTags it ON i.Id = it.ItemId
WHERE it.Tag = '8';

กรณีที่ยอมรับ FIND_IN_SET() ได้

  • ตารางเล็ก (< 1000 แถว)
  • ข้อมูลไม่เปลี่ยนบ่อย (Read-heavy)
  • Legacy System ที่แก้ Schema ไม่ได้
  • Ad-hoc Query ชั่วคราว

สรุป

ใช้ FIND_IN_SET(value, csv_column) เพื่อค้นหาค่าในสตริงคั่นจุลภาค คืนค่า > 0 = พบ, 0 = ไม่พบ แต่ไม่ใช้ Index ควร Normalize ข้อมูลเพื่อประสิทธิภาพยาวนาน