เมื่อต้องการ LIMIT ก่อน แล้วค่อย ORDER BY ใหม่ (Order after Limit) ต้องใช้ Subquery: Subquery ด้านในทำ LIMIT และ ORDER แรก แล้ว Outer query ทำ ORDER BY อีกครั้ง
รูปแบบคำสั่ง
SELECT * FROM (
SELECT * FROM table_name
ORDER BY column1 DESC
LIMIT n
) AS subquery
ORDER BY column2 ASC;
ตัวอย่างการใช้งาน
1. สร้างตารางและเพิ่มข้อมูล 9 แถว
CREATE TABLE OrderByAfterLimit (
Id INT NOT NULL AUTO_INCREMENT,
UserName VARCHAR(20),
UserAge INT,
PRIMARY KEY (Id)
);
INSERT INTO OrderByAfterLimit (UserName, UserAge) VALUES
('John', 23), ('Larry', 21), ('Bob', 26),
('James', 22), ('Robert', 28), ('Mike', 29),
('Carol', 24), ('David', 20), ('Maxwell', 30);
ข้อมูลในตาราง:
+----+----------+---------+
| Id | UserName | UserAge |
+----+----------+---------+
| 1 | John | 23 |
| 2 | Larry | 21 |
| 3 | Bob | 26 |
| 4 | James | 22 |
| 5 | Robert | 28 |
| 6 | Mike | 29 |
| 7 | Carol | 24 |
| 8 | David | 20 |
| 9 | Maxwell | 30 |
+----+----------+---------+
2. หา 9 คนอายุมากที่สุด (DESC) แล้วเรียงตามชื่อ (ASC)
SELECT * FROM (
SELECT * FROM OrderByAfterLimit
ORDER BY UserAge DESC
LIMIT 9
) AS tbl1
ORDER BY UserName;
ผลลัพธ์:
+----+----------+---------+
| Id | UserName | UserAge |
+----+----------+---------+
| 3 | Bob | 26 |
| 7 | Carol | 24 |
| 8 | David | 20 |
| 4 | James | 22 |
| 1 | John | 23 |
| 2 | Larry | 21 |
| 9 | Maxwell | 30 |
| 6 | Mike | 29 |
| 5 | Robert | 28 |
+----+----------+---------+
คำอธิบายลำดับการทำงาน
- Inner Query: เรียงตาม UserAge DESC (มากไปน้อย) → LIMIT 9 (เอาทั้งหมด 9 แถว)
- Outer Query: รับ 9 แถวจาก Inner → เรียงตาม UserName ASC (A-Z)
กรณีใช้งานจริง
Top-N แล้วเรียงอีกแบบ
-- หา 10 สินค้าขายดีสุด แล้วเรียงตามชื่อ
SELECT * FROM (
SELECT * FROM products ORDER BY sales DESC LIMIT 10
) AS top10 ORDER BY product_name;
Pagination พร้อมเรียงลำดับเฉพาะหน้า
-- หน้าที่ 2: ข้าม 10 แถว แล้ว LIMIT 10, เรียงในหน้าเฉพาะ
SELECT * FROM (
SELECT * FROM products ORDER BY created_at DESC LIMIT 20
) AS paged ORDER BY price ASC LIMIT 10 OFFSET 10;
MySQL 8.0+: ใช้ Window Function
WITH ranked AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY UserAge DESC) AS rn
FROM OrderByAfterLimit
)
SELECT * FROM ranked WHERE rn <= 9 ORDER BY UserName;
Window Function ทำให้เขียนอ่านง่ายกว่า และประสิทธิภาพดีกว่า Subquery
สรุป
- Subquery: ใช้ได้ทุกเวอร์ชัน, เข้าใจง่าย
- CTE + Window Function: MySQL 8.0+, แนะนำสำหรับความซับซ้อนสูง
- จำไว้: Inner ORDER + LIMIT ก่อน, Outer ORDER หลัง