สถานการณ์
คอลัมน์ VARCHAR เก็บตัวเลขคั่นด้วย Comma (CSV format) เช่น '80.2,90.5,88.90' ต้องการค้นหาแถวที่มีตัวเลข '80' ปรากฏอยู่
วิธีง่าย: ใช้ LIKE
WHERE column LIKE '%80%' - ค้นหาสตริงที่มี '80' อยู่ที่ไหนก็ได้
ตัวอย่างการใช้งาน
1. สร้างตาราง
mysql> CREATE TABLE DemoTable (
-> Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> DoubleValue VARCHAR(20)
-> );
Query OK, 0 rows affected (0.58 sec)
2. เพิ่มข้อมูล
mysql> INSERT INTO DemoTable(DoubleValue) VALUES('80.2,90.5,88.90');
Query OK, 1 row affected (0.44 sec)
mysql> INSERT INTO DemoTable(DoubleValue) VALUES('78.56,45.80,88,45.6');
Query OK, 1 row affected (0.21 sec)
mysql> INSERT INTO DemoTable(DoubleValue) VALUES('12.34,90.06,89.90');
Query OK, 1 row affected (0.11 sec)
3. ค้นหาด้วย LIKE '%80%'
mysql> SELECT * FROM DemoTable WHERE DoubleValue LIKE '%80%';
ผลลัพธ์:
+----+---------------------+ | Id | DoubleValue | +----+---------------------+ | 1 | 80.2,90.5,88.90 | | 2 | 78.56,45.80,88,45.6 | +----+---------------------+ 2 rows in set (0.00 sec)
ปัญหาของ LIKE (False Positives)
ค้นหา '80' แต่จับได้:
80.2✓ (ถูกต้อง)45.80✓ (ถูกต้อง - เป็น 80 อยู่ในทศนิยม)180✗ (False positive - เป็น 180 ไม่ใช่ 80)800✗ (False positive)
วิธีแก้ที่แม่นยำกว่า
1. ใช้ REGEXP (MySQL 8.0+)
-- จับ 80 ที่เป็นตัวเลขเต็มตัว คั่นด้วย Comma หรืออยู่ปลาย/หัว WHERE DoubleValue REGEXP '(^|,)80(,|$)'
2. ใช้ FIND_IN_SET (สำหรับ Integer เท่านั้น)
WHERE FIND_IN_SET('80', DoubleValue) > 0
ข้อจำกัด: FIND_IN_SET คาดหวัง Integer ไม่มีทศนิยม
3. Normalize ข้อมูล (แนะนำ)
-- ตารางหลัก
CREATE TABLE Records (Id INT PRIMARY KEY, ...);
-- ตารางค่า (Normalized)
CREATE TABLE RecordValues (
RecordId INT,
Value DECIMAL(10,2),
PRIMARY KEY (RecordId, Value),
FOREIGN KEY (RecordId) REFERENCES Records(Id)
);
สรุปการเลือกวิธี
| วิธี | ความแม่นยำ | Performance | เหมาะสำหรับ |
|---|---|---|---|
| LIKE '%val%' | ต่ำ (False +) | ช้า (No Index) | Ad-hoc, ข้อมูลน้อย |
| REGEXP | สูง | ช้า (No Index) | Pattern ซับซ้อน |
| FIND_IN_SET | สูง (Integer) | ปานกลาง | CSV Integer |
| Normalized Table | สูงสุด | เร็ว (Index) | Production, ข้อมูลเยอะ |