Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

MySQL ORDER BY คอลัมน์ VARCHAR ให้เรียงแบบตัวเลข (CAST / +0)

คอลัมน์ 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 แทนถ้าเป็นไปได้