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

การจัดเรียง ORDER BY ตามเงื่อนไขใน MySQL ด้วย IF()

การจัดลำดับข้อมูลตามเงื่อนไขเฉพาะด้วย ORDER BY IF()

ใช้ ORDER BY IF(condition, value_if_true, value_if_false) เพื่อจัดลำดับ โดยให้แถวที่ตรงเงื่อนไขอยู่หน้า/หลังตามต้องการ

รูปแบบคำสั่ง

SELECT * FROM table_name 
ORDER BY IF(column = 'target_value', 1, 0) ASC, other_column DESC;

ตัวอย่าง: ให้ 'Sam' อยู่ท้ายสุด แล้วจัดอีกตัวจาก Score มากไปน้อย

1. สร้างตารางและเพิ่มข้อมูล

CREATE TABLE DemoTable (Name VARCHAR(50), Score INT);
INSERT INTO DemoTable VALUES 
('Chris', 98), ('David', 45), ('Bob', 56), ('Sam', 89), ('Carol', 78);

2. ดูข้อมูลก่อน

SELECT * FROM DemoTable;

ผลลัพธ์: Chris(98), David(45), Bob(56), Sam(89), Carol(78)

3. ORDER BY IF: Sam อยู่ท้าย (IF=1), อื่นๆ เรียง Score DESC

SELECT * FROM DemoTable 
ORDER BY IF(Name = 'Sam', 1, 0) ASC, Score DESC;

ผลลัพธ์:

+-------+-------+
| Name  | Score |
+-------+-------+
| Chris | 98    |
| Carol | 78    |
| Bob   | 56    |
| David | 45    |
| Sam   | 89    |
+-------+-------+

การทำงานของ IF() ใน ORDER BY

  • IF(Name = 'Sam', 1, 0) คืนค่า 1 สำหรับ Sam, 0 สำหรับคนอื่น
  • ASC: 0 (คนอื่น) อยู่หน้า, 1 (Sam) อยู่ท้าย
  • ภายในกลุ่มเดียวกัน (IF=0) เรียงตาม Score DESC

ใช้ CASE WHEN แทน IF (ยืดหยุ่นกว่า)

ORDER BY CASE 
    WHEN Name = 'Sam' THEN 3
    WHEN Name = 'VIP' THEN 2
    ELSE 1
END DESC, Score DESC;

กรณีใช้งานจริง

  • Priority Sorting: 'Urgent' ก่อน, 'Normal' ท้าย
  • Pin/Featured Items: Featured อยู่บนสุด
  • Custom Sort Order: กำหนดลำดับหมวดหมู่เอง

ประสิทธิภาพ

  • IF() และ CASE ใน ORDER BY ทำให้ **ไม่สามารถใช้ Index สำหรับ Sorting ได้** (Filesort)
  • หากตารางใหญ่ ควรพิจารณา:
    • เพิ่ม Priority Column (TINYINT) + Index
    • คำนวณ Priority ใน Application Layer
    • ใช้ Generated Column + Index

Generated Column สำหรับ Sorting เร็ว

ALTER TABLE DemoTable 
ADD COLUMN SortPriority TINYINT 
GENERATED ALWAYS AS (IF(Name = 'Sam', 1, 0)) STORED,
ADD INDEX idx_sort (SortPriority, Score DESC);

-- Query ใช้ Index
SELECT * FROM DemoTable ORDER BY SortPriority ASC, Score DESC;