คอลัมน์ VARCHAR จะเรียงแบบสตริง (1, 10, 2, 3...) ใช้ +0 หรือ CAST() บังคับให้เรียงแบบตัวเลข
ปัญหา: เรียงแบบสตริง (String Sort)
mysql> CREATE TABLE selectOrderdemo (
-> Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> Name VARCHAR(100),
-> RankNumber VARCHAR(100)
-> );
mysql> INSERT INTO selectOrderdemo(Name, RankNumber) VALUES
('Larry', '-100'), ('John', '50'), ('Bob', '0'), ('Carol', '-110'), ('David', '98');
mysql> SELECT * FROM selectOrderdemo;
ผลลัพธ์ (เรียงตาม Id):
+----+-------+------------+ | Id | Name | RankNumber | +----+-------+------------+ | 1 | Larry | -100 | | 2 | John | 50 | | 3 | Bob | 0 | | 4 | Carol | -110 | | 5 | David | 98 | +----+-------+------------+
ORDER BY RankNumber (แบบ String - ผิด)
mysql> SELECT RankNumber FROM selectOrderdemo ORDER BY RankNumber;
ผลลัพธ์: -100, -110, 0, 50, 98 (เรียงตามตัวอักษร: -1... แล้ว 0... แล้ว 5... แล้ว 9...)
แก้ไข: ใช้ +0 บังคับแปลงเป็นตัวเลข
กรณีที่ 1: เรียงมากไปน้อย (DESC)
mysql> SELECT RankNumber FROM selectOrderdemo ORDER BY RankNumber + 0 DESC;
ผลลัพธ์: 98, 50, 0, -100, -110 ✓
กรณีที่ 2: เรียงน้อยไปมาก (ASC)
mysql> SELECT RankNumber FROM selectOrderdemo ORDER BY RankNumber + 0;
ผลลัพธ์: -110, -100, 0, 50, 98 ✓
กรณีที่ 3: SELECT * เรียงตามตัวเลข
mysql> SELECT * FROM selectOrderdemo ORDER BY RankNumber + 0 DESC;
ผลลัพธ์:
+----+-------+------------+ | Id | Name | RankNumber | +----+-------+------------+ | 5 | David | 98 | | 2 | John | 50 | | 3 | Bob | 0 | | 1 | Larry | -100 | | 4 | Carol | -110 | +----+------------+
วิธีอื่น: CAST()
ORDER BY CAST(RankNumber AS SIGNED) ORDER BY CAST(RankNumber AS DECIMAL(10,2)) ORDER BY CAST(RankNumber AS UNSIGNED) -- เฉพาะบวก
เปรียบเทียบ +0 vs CAST()
| วิธี | ข้อดี | ข้อเสีย |
|---|---|---|
| + 0 | สั้น เขียนง่าย เร็ว | Implicit conversion อาจสับสน |
| CAST() | ชัดเจน รองรับชนิดข้อมูลเฉพาะ | ยาวกว่า |
ข้อควรระวัง
- ค่าที่ไม่ใช่ตัวเลข (เช่น 'abc') จะกลายเป็น 0
- ค่า NULL จะอยู่ก่อนสุด (ASC) หรือหลังสุด (DESC) ขึ้นกับ DB
- ควรแก้โครงสร้างตารางให้เป็น INT/UNSIGNED INT แทนถ้าเป็นไปได้