ใช้ Subquery ร่วมกับ MIN() และ MAX() เพื่อหา ID แรกและสุดท้าย แล้วตัดทิ้งด้วย NOT IN
Syntax
SELECT * FROM table_name
WHERE id_column NOT IN (
(SELECT MIN(id_column) FROM table_name WHERE condition),
(SELECT MAX(id_column) FROM table_name WHERE condition)
) AND condition;
ตัวอย่างการใช้งาน
1. สร้างตารางและเพิ่มข้อมูล
mysql> create table DemoTable1917 (
-> StudentId int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> StudentCode int,
-> StudentMarks int
-> ); Query OK, 0 rows affected (0.00 sec)
mysql> insert into DemoTable1917(StudentCode,StudentMarks) values(78,95); Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1917(StudentCode,StudentMarks) values(78,96); Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1917(StudentCode,StudentMarks) values(78,97); Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1917(StudentCode,StudentMarks) values(78,98); Query OK, 1 row affected (0.00 sec)
mysql> insert into DemoTable1917(StudentCode,StudentMarks) values(78,99); Query OK, 1 row affected (0.00 sec)
ข้อมูลทั้งหมด:
mysql> select * from DemoTable1917;
+-----------+-------------+--------------+ | StudentId | StudentCode | StudentMarks | +-----------+-------------+--------------+ | 1 | 78 | 95 | | 2 | 78 | 96 | | 3 | 78 | 97 | | 4 | 78 | 98 | | 5 | 78 | 99 | +-----------+-------------+--------------+ 5 rows in set (0.00 sec)
2. ดึงข้อมูลยกเว้นแถวแรก (Id=1) และแถวสุดท้าย (Id=5) ของ StudentCode=78
mysql> select * from DemoTable1917
-> where StudentId NOT IN (
-> (select min(StudentId) from DemoTable1917 where StudentCode=78),
-> (select max(StudentId) from DemoTable1917 where StudentCode=78)
-> ) and StudentCode=78;
ผลลัพธ์:
+-----------+-------------+--------------+ | StudentId | StudentCode | StudentMarks | +-----------+-------------+--------------+ | 2 | 78 | 96 | | 3 | 78 | 97 | | 4 | 78 | 98 | +-----------+-------------+--------------+ 3 rows in set (0.00 sec)
วิธีอื่น: ใช้ LIMIT และ OFFSET (MySQL 8.0+)
-- ข้าม 1 แถวแรก และ 1 แถวสุดท้าย (ต้องรู้จำนวนรวม) SELECT * FROM DemoTable1917 WHERE StudentCode = 78 ORDER BY StudentId LIMIT (SELECT COUNT(*) - 2 FROM DemoTable1917 WHERE StudentCode = 78) OFFSET 1;
วิธีอื่น: ใช้ ROW_NUMBER() (MySQL 8.0+)
WITH ranked AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY StudentCode ORDER BY StudentId) as rn,
COUNT(*) OVER (PARTITION BY StudentCode) as cnt
FROM DemoTable1917
WHERE StudentCode = 78
)
SELECT * FROM ranked WHERE rn > 1 AND rn < cnt;
เปรียบเทียบวิธี
| วิธี | MySQL Version | ประสิทธิภาพ | ความซับซ้อน |
|---|---|---|---|
| NOT IN + MIN/MAX | All | ดี | ต่ำ |
| LIMIT OFFSET + Subquery | All | ปานกลาง | ปานกลาง |
| ROW_NUMBER() Window | 8.0+ | ดีมาก | สูง |
สรุป: ใช้ WHERE id NOT IN (MIN(id), MAX(id)) วิธีง่ายที่สุดรองรับทุกเวอร์ชัน สำหรับ MySQL 8.0+ แนะนำ ROW_NUMBER() Window Function ความชัดเจนและประสิทธิภาพดีกว่า