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

แบ่งแสดงข้อมูลสลับกัน ASC/DESC ใน MySQL ด้วยค่ากลาง

เทคนิคการแสดงข้อมูลสลับกันระหว่างค่าน้อยที่สุดและมากที่สุด (1, 10, 2, 9, 3, 8...) โดยใช้ค่ากลาง (Median) เป็นจุดอ้างอิงในการคำนวณลำดับ

สร้างตารางและข้อมูล 1-10

mysql> create table DemoTable (UserId int NOT NULL AUTO_INCREMENT PRIMARY KEY);
mysql> insert into DemoTable values(); -- ทำ 10 ครั้ง

หาค่ากลาง (Middle Value)

mysql> set @middleValue = (select max(UserId) from DemoTable) / 2;

คำสั่งเรียงสลับ ASC/DESC

mysql> select * from DemoTable 
ORDER BY (IF(UserId < @middleValue, @middleValue * 2 - UserId, UserId - 1)) DESC, UserId ASC;

ผลลัพธ์: 1, 10, 2, 9, 3, 8, 4, 7, 6, 5

+--------+
| UserId |
+--------+
| 1      |
| 10     |
| 2      |
| 9      |
| 3      |
| 8      |
| 4      |
| 7      |
| 6      |
| 5      |
+--------+

หลักการคำนวณ

  • ค่ากลาง = MAX/2 = 5
  • ค่าน้อยกว่ากลาง: @middleValue * 2 - UserId → 1→9, 2→8, 3→7, 4→6, 5→5
  • ค่ามากกว่ากลาง: UserId - 1 → 6→5, 7→6, 8→7, 9→8, 10→9
  • เรียง DESC ตามค่าที่คำนวณได้ → ได้ลำดับสลับ
  • ใช้ UserId ASC เป็น Tie-breaker

กรณีข้อมูลไม่ต่อเนื่องหรือมีค่าซ้ำ

-- ใช้ ROW_NUMBER() ใน MySQL 8.0+ แทน
WITH ranked AS (
    SELECT UserId, ROW_NUMBER() OVER (ORDER BY UserId) as rn,
           COUNT(*) OVER() as total
    FROM DemoTable
)
SELECT UserId FROM ranked
ORDER BY 
    CASE WHEN rn <= total/2 THEN total/2 * 2 - rn + 1 ELSE rn - total/2 END DESC,
    UserId;

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

  • จัดทีมแข่งขัน: ทีมอันดับ 1 vs อันดับสุดท้าย, 2 vs รองสุดท้าย
  • จัดที่นั่งสัมภาษณ์/ประชุม: สลับระหว่าง Junior/Senior
  • Load Balancing: กระจาย Request ไป Server ต่างๆ