Tóm tắt
Dùng MIN() và MAX() trên cột ID (hoặc cột sắp xếp) kết hợp UNION để lấy hàng đầu và hàng cuối.
Cú pháp
SELECT * FROM bang WHERE cot_id = (SELECT MIN(cot_id) FROM bang)
UNION
SELECT * FROM bang WHERE cot_id = (SELECT MAX(cot_id) FROM bang);
Ví dụ
1. Tạo bảng nhân viên
CREATE TABLE FirstAndLastDataDemo (
EmployeeId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
EmployeeName VARCHAR(20),
EmployeeAge INT
);
2. Dữ liệu 9 hàng
INSERT INTO FirstAndLastDataDemo (EmployeeName, EmployeeAge) VALUES
('John',23), ('Bob',13), ('Larry',24), ('Sam',14),
('Mike',31), ('James',18), ('Maxwell',28), ('David',27), ('Chris',22);
3. Truy vấn đầu + cuối
SELECT * FROM FirstAndLastDataDemo
WHERE EmployeeId = (SELECT MIN(EmployeeId) FROM FirstAndLastDataDemo)
UNION
SELECT * FROM FirstAndLastDataDemo
WHERE EmployeeId = (SELECT MAX(EmployeeId) FROM FirstAndLastDataDemo);
4. Kết quả
+------------+--------------+-------------+
| EmployeeId | EmployeeName | EmployeeAge |
+------------+--------------+-------------+
| 1 | John | 23 |
| 9 | Chris | 22 |
+------------+--------------+-------------+
Cách thay thế (MySQL 8.0+)
-- Cách 1: UNION ALL + LIMIT (nhanh hơn nếu có index)
(SELECT * FROM bang ORDER BY id LIMIT 1)
UNION ALL
(SELECT * FROM bang ORDER BY id DESC LIMIT 1);
-- Cách 2: Window function
SELECT * FROM (
SELECT *,
ROW_NUMBER() OVER (ORDER BY id) AS rn_asc,
ROW_NUMBER() OVER (ORDER BY id DESC) AS rn_desc
FROM bang
) t WHERE rn_asc = 1 OR rn_desc = 1;
Lưu ý
- Cần cột xác định thứ tự (ID, created_at, sequence).
- UNION loại trùng – nếu bảng chỉ 1 hàng, chỉ trả 1 hàng. Dùng UNION ALL để luôn 2 hàng.
- Hiệu năng: MIN/MAX trên PK/Index rất nhanh (O(1) hoặc O(log n)).