ปัญหา: ข้อมูลมี Space นำหน้า/ท้าย ทำให้ JOIN/WHERE ไม่ Match
ข้อมูล " John " และ "John" ดูเหมือนกันแต่ MySQL เห็นว่าต่างกัน ใช้ LTRIM() (ตัด Space ซ้าย) และ RTRIM() (ตัด Space ขวา) หรือ TRIM() (ตัดทั้งสองข้าง)
ตัวอย่าง
CREATE TABLE DemoTable614 (
EnterName VARCHAR(100),
ReenterName VARCHAR(100)
);
INSERT INTO DemoTable614 VALUES
(' John ', 'John'),
('Carol ', 'Bob'),
('David ', 'David');
Query แบบปกติ (ไม่ Match):
SELECT * FROM DemoTable614 WHERE EnterName = ReenterName;
ผลลัพธ์: แค่ David (เพราะ "David " ≠ "David")
Query ใช้ TRIM (Match ได้ถูกต้อง)
SELECT * FROM DemoTable614
WHERE LTRIM(RTRIM(EnterName)) = LTRIM(RTRIM(ReenterName));
หรือสั้นกว่า:
SELECT * FROM DemoTable614
WHERE TRIM(EnterName) = TRIM(ReenterName);
ผลลัพธ์: John และ David
+------------+--------------+
| EnterName | ReenterName |
+------------+--------------+
| John | John |
| David | David |
+------------+--------------+
ฟังก์ชัน Trim ต่างๆ
| Function | ผลลัพธ์ | ตัวอย่าง |
|---|---|---|
| TRIM(str) | ตัด Space ทั้ง 2 ข้าง | TRIM(' abc ') = 'abc' |
| LTRIM(str) | ตัด Space ซ้าย | LTRIM(' abc') = 'abc' |
| RTRIM(str) | ตัด Space ขวา | RTRIM('abc ') = 'abc' |
| TRIM(BOTH 'x' FROM str) | ตัดตัวอักษร x ทั้ง 2 ข้าง | TRIM(BOTH 'x' FROM 'xxabcxx') = 'abc' |
| TRIM(LEADING 'x' FROM str) | ตัดตัวอักษร x ซ้าย | TRIM(LEADING '0' FROM '00123') = '123' |
| TRIM(TRAILING 'x' FROM str) | ตัดตัวอักษร x ขวา | TRIM(TRAILING '.' FROM '1.2300') = '1.23' |
Best Practice: ป้องกันที่ต้นทาง
- Application Level: Trim ก่อน Insert/Update (PHP:
trim(), Python:.strip()) - Database Level: ใช้ Trigger
-- Trigger ตัด Space อัตโนมัติก่อน Insert
CREATE TRIGGER trim_before_insert
BEFORE INSERT ON DemoTable614
FOR EACH ROW
BEGIN
SET NEW.EnterName = TRIM(NEW.EnterName);
SET NEW.ReenterName = TRIM(NEW.ReenterName);
END;
Performance Note
ใช้ Function บน Column ใน WHERE (WHERE TRIM(col) = 'val') จะทำให้ Index ไม่ถูกใช้งาน (Non-SARGable)
แนะนำ: เก็บข้อมูล Trim แล้วตั้งแต่แรก หรือเพิ่ม Generated Column ที่ Trim แล้ว Index คอลัมน์นั้น