Giới thiệu
MySQL cho phép mệnh đề ORDER BY và LIMIT trong câu lệnh DELETE để xóa chính xác N hàng theo thứ tự sắp xếp cụ thể.
1. Tạo bảng và dữ liệu
mysql> create table DemoTable (
-> Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> FirstName varchar(20)
-> );
Query OK, 0 rows affected (0.65 sec)
mysql> insert into DemoTable(FirstName) values('Chris');
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable(FirstName) values('Adam');
Query OK, 1 row affected (0.11 sec)
mysql> insert into DemoTable(FirstName) values('John');
Query OK, 1 row affected (0.11 sec)
mysql> insert into DemoTable(FirstName) values('David');
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable(FirstName) values('Mike');
Query OK, 1 row affected (0.19 sec)
mysql> insert into DemoTable(FirstName) values('Carol');
Query OK, 1 row affected (0.17 sec)
mysql> insert into DemoTable(FirstName) values('Sam');
Query OK, 1 row affected (0.13 sec)
2. Dữ liệu gốc (theo ID)
mysql> select *from DemoTable;
+----+-----------+ | Id | FirstName | +----+-----------+ | 1 | Chris | | 2 | Adam | | 3 | John | | 4 | David | | 5 | Mike | | 6 | Carol | | 7 | Sam | +----+-----------+ 7 rows in set (0.00 sec)
3. Xóa 4 hàng đầu theo tên A-Z
mysql> delete from DemoTable order by FirstName asc limit 4; Query OK, 4 rows affected (0.19 sec)
Thứ tự tên A-Z: Adam, Carol, Chris, David, John, Mike, Sam
Xóa 4 hàng đầu: Adam, Carol, Chris, David
4. Kết quả còn lại
mysql> select *from DemoTable;
+----+-----------+ | Id | FirstName | +----+-----------+ | 3 | John | | 5 | Mike | | 7 | Sam | +----+-----------+ 3 rows in set (0.00 sec)
⚠️ Cảnh báo quan trọng:
DELETE ... ORDER BY ... LIMITlà syntax MySQL riêng, không chuẩn SQL- Không có WHERE → xóa theo thứ tự vật lý/sắp xếp, rất nguy hiểm nếu hiểu nhầm
- Luôn test với
SELECT ... ORDER BY ... LIMITtrước khi DELETE - Replication: Câu lệnh này không an toàn cho statement-based replication (cần row-based)
Cách an toàn hơn (chuẩn SQL):
DELETE FROM DemoTable
WHERE Id IN (
SELECT Id FROM DemoTable
ORDER BY FirstName ASC
LIMIT 4
);
(MySQL không cho phép SELECT cùng bảng trong DELETE, cần wrap thêm lớp subquery hoặc dùng JOIN)