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

MySQL: เรียงลำดับใหม่หลัง LIMIT ด้วย Subquery (Order After Limit)

เมื่อต้องการ 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 |
+----+----------+---------+

คำอธิบายลำดับการทำงาน

  1. Inner Query: เรียงตาม UserAge DESC (มากไปน้อย) → LIMIT 9 (เอาทั้งหมด 9 แถว)
  2. 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 หลัง