เมื่อเปรียบเทียบคอลัมน์ VARCHAR กับตัวเลข 0 MySQL จะทำ Implicit Type Conversion แปลงสตริงเป็นตัวเลข ซึ่งอาจให้ผลลัพธ์ไม่คาดคิด
ตัวอย่างการทดสอบ
1. สร้างตาราง VARCHAR
mysql> CREATE TABLE DemoTable1791 (
FirstName VARCHAR(20)
);
Query OK, 0 rows affected (0.00 sec)
2. เพิ่มข้อมูล (เฉพาะข้อความ ไม่มีตัวเลข)
mysql> INSERT INTO DemoTable1791 VALUES('David');
mysql> INSERT INTO DemoTable1791 VALUES('John');
mysql> INSERT INTO DemoTable1791 VALUES('Carol');
3. แสดงข้อมูล
mysql> SELECT * FROM DemoTable1791; +-----------+ | FirstName | +-----------+ | David | | John | | Carol | +-----------+
4. Query: WHERE FirstName = 0 (เปรียบเทียบ VARCHAR กับ 0)
mysql> SELECT * FROM DemoTable1791 WHERE FirstName = 0;
5. ผลลัพธ์ (⚠️ มี Warning)
+-----------+ | FirstName | +-----------+ | David | | John | | Carol | +-----------+ 3 rows in set, 3 warnings (0.00 sec)
ทำไมถึงคืนทุกแถว?
- MySQL แปลง
'David','John','Carol'เป็นตัวเลข → ทุกค่ากลายเป็น0(เพราะไม่ขึ้นต้นด้วยตัวเลข) - ดังนั้น
0 = 0เป็น TRUE ทุกแถว - เกิด Warning: Truncated incorrect DOUBLE value ทุกแถว
การทดสอบเพิ่มเติม
mysql> SELECT 'David' = 0, '123abc' = 0, '0' = 0, '0abc' = 0; +-------------+--------------+---------+-----------+ | 'David' = 0 | '123abc' = 0 | '0' = 0 | '0abc' = 0 | +-------------+--------------+---------+-----------+ | 1 | 0 | 1 | 1 | +-------------+--------------+---------+-----------+
คำอธิบาย:
'David' = 0→ TRUE (1) เพราะ 'David' → 0'123abc' = 0→ FALSE (0) เพราะ '123abc' → 123'0' = 0→ TRUE (1) เพราะ '0' → 0'0abc' = 0→ TRUE (1) เพราะ '0abc' → 0 (อ่านเฉพาะ 0 นำหน้า)
Best Practice: หลีกเลี่ยง Implicit Conversion
-- ✅ ดี: เปรียบเทียบสตริงกับสตริง WHERE FirstName = '0' -- ✅ ดี: แปลงชนิดข้อมูลชัดเจน WHERE CAST(FirstName AS UNSIGNED) = 0 -- ✅ ดี: ใช้ STRCMP สำหรับเปรียบเทียบสตริง WHERE STRCMP(FirstName, '0') = 0
สรุป
VARCHAR = 0 จะแปลง VARCHAR เป็นตัวเลข อักขระไม่ใช่ตัวเลขนำหน้า → 0 ทำให้ 'David' = 0 เป็น TRUE ควรเปรียบเทียบชนิดข้อมูลเดียวกันเสมอ (VARCHAR = 'string', INT = 0)