ปัญหา
ข้อมูลในคอลัมน์หนึ่งเก็บหลายค่าคั่นด้วย Pipe (|) เช่น 8|56|78|45 ต้องการค้นหาแถวที่มีค่าเฉพาะ (เช่น 8) แต่ไม่ต้องการจับค่าที่เป็นส่วนหนึ่งของตัวเลขอื่น (เช่น 18, 88, 98)
วิธีแก้: ใช้ Regular Expression (REGEXP)
ใช้ Pattern \\|8\\| เพื่อจับค่า 8 ที่อยู่ระหว่าง Pipe ทั้งสองข้าง (Escaped backslash เนื่องจาก Pipe เป็น Special character ใน Regex)
ตัวอย่างการใช้งาน
1. สร้างตาราง
mysql> CREATE TABLE DemoTable (
-> Value VARCHAR(60)
-> );
Query OK, 0 rows affected (0.48 sec)
2. เพิ่มข้อมูลทดสอบ
mysql> INSERT INTO DemoTable VALUES('8|56|78|45');
Query OK, 1 row affected (0.24 sec)
mysql> INSERT INTO DemoTable VALUES('9876');
Query OK, 1 row affected (0.11 sec)
mysql> INSERT INTO DemoTable VALUES('98|8');
Query OK, 1 row affected (0.17 sec)
mysql> INSERT INTO DemoTable VALUES('3|8|9');
Query OK, 1 row affected (0.13 sec)
mysql> INSERT INTO DemoTable VALUES('97|94');
Query OK, 1 row affected (0.17 sec)
mysql> INSERT INTO DemoTable VALUES('103|104|110|8|97');
Query OK, 1 row affected (0.10 sec)
3. แสดงข้อมูลทั้งหมด
mysql> SELECT * FROM DemoTable;
ผลลัพธ์:
+------------------+ | Value | +------------------+ | 8|56|78|45 | | 9876 | | 98|8 | | 3|8|9 | | 97|94 | | 103|104|110|8|97 | +------------------+ 6 rows in set (0.00 sec)
4. ค้นหาแถวที่มีค่า 8 แยกต่างหาก (ไม่ใช่ส่วนหนึ่งของตัวเลขอื่น)
mysql> SELECT * FROM DemoTable
-> WHERE Value REGEXP '\\|8\\|';
ผลลัพธ์:
+------------------+ | Value | +------------------+ | 3|8|9 | | 103|104|110|8|97 | +------------------+ 2 rows in set (0.00 sec)
Pattern ที่ใช้
| Pattern | ความหมาย | จับได้ | ไม่จับ |
|---|---|---|---|
\\|8\\| |
8 ระหว่าง Pipe | 3|8|9, 103|...|8|97 | 8|56, 98|8, 9876 |
^8\\| |
เริ่มต้นด้วย 8| | 8|56|78|45 | อื่นๆ |
\\|8$ |
จบด้วย |8 | 98|8 | อื่นๆ |
(^|\\|)8(\\|$) |
8 แยกต่างหาก (เริ่ม/กลาง/ท้าย) | ทั้ง 4 แถวที่มี 8 | 9876, 97|94 |
ข้อควรระวัง
- REGEXP ไม่ใช้ Index ได้ → Full table scan (ช้าบนตารางใหญ่)
- ควร Normalize ข้อมูล (แยกคอลัมน์/ตาราง) หากค้นหาบ่อย
- MySQL 8.0+ รองรับ REGEXP_REPLACE() สำหรับแทนที่
- ใช้
RLIKEเป็น Alias ของ REGEXP
แนวทางแก้ไขระยะยาว
ออกแบบฐานข้อมูลให้เป็น Normalized Form (1NF) โดยแยกค่าที่คั่นด้วย Pipe ออกเป็นตารางความสัมพันธ์ (Many-to-Many) จะทำให้ Query เร็วขึ้นและรักษาความสมบูรณ์ของข้อมูลได้ดีกว่า