Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Lấy tất cả hàng trừ hàng đầu và cuối trong MySQL

Vấn đề: Loại bỏ hàng đầu tiên và cuối cùng theo nhóm

Cần truy vấn các hàng "giữa" – bỏ qua hàng có ID nhỏ nhất và lớn nhất trong mỗi nhóm (ví dụ: theo StudentCode).

Giải pháp: Subquery với MIN() và MAX()

Dùng NOT IN kết hợp subquery lấy MIN(StudentId) và MAX(StudentId) cho từng nhóm.

1. Tạo bảng và dữ liệu

CREATE TABLE DemoTable (
    StudentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    StudentCode INT,
    StudentMarks INT
);

INSERT INTO DemoTable (StudentCode, StudentMarks) VALUES
(78, 95), (78, 96), (78, 97), (78, 98), (78, 99);

2. Dữ liệu đầy đủ

+-----------+-------------+--------------+
| StudentId | StudentCode | StudentMarks |
+-----------+-------------+--------------+
|         1 |          78 |           95 |
|         2 |          78 |           96 |
|         3 |          78 |           97 |
|         4 |          78 |           98 |
|         5 |          78 |           99 |
+-----------+-------------+--------------+

3. Truy vấn lấy hàng giữa

SELECT * FROM DemoTable
WHERE StudentId NOT IN (
    (SELECT MIN(StudentId) FROM DemoTable WHERE StudentCode = 78),
    (SELECT MAX(StudentId) FROM DemoTable WHERE StudentCode = 78)
) AND StudentCode = 78;

4. Kết quả (bỏ ID 1 và 5)

+-----------+-------------+--------------+
| StudentId | StudentCode | StudentMarks |
+-----------+-------------+--------------+
|         2 |          78 |           96 |
|         3 |          78 |           97 |
|         4 |          78 |           98 |
+-----------+-------------+--------------+

Cách hiện đại hơn (MySQL 8.0+): Window Functions

WITH Ranked AS (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY StudentCode ORDER BY StudentId) AS rn_asc,
           ROW_NUMBER() OVER (PARTITION BY StudentCode ORDER BY StudentId DESC) AS rn_desc
    FROM DemoTable
)
SELECT StudentId, StudentCode, StudentMarks
FROM Ranked
WHERE rn_asc > 1 AND rn_desc > 1;

Ưu điểm: Hiệu suất tốt hơn trên dữ liệu lớn, dễ mở rộng cho nhiều nhóm.

Lưu ý

  • Đảm bảo cột sắp xếp (StudentId) xác định thứ tự rõ ràng.
  • Nếu nhóm chỉ có 1 hoặc 2 hàng, kết quả sẽ rỗng – hợp lý.
  • Subquery NOT IN có thể chậm trên bảng lớn; ưu tiên NOT EXISTS hoặc Window Functions.