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

หาแถวก่อนหน้าและถัดไปในคำสั่งเดียวด้วย UNION ใน MySQL

ใช้ UNION รวมผลลัพธ์ของ 2 Subquery: หา ID มากกว่าค่าที่กำหนด (ถัดไป) และ น้อยกว่า (ก่อนหน้า)

รูปแบบคำสั่ง

(SELECT * FROM yourTable WHERE id > target_id ORDER BY id ASC LIMIT 1)
UNION
(SELECT * FROM yourTable WHERE id < target_id ORDER BY id DESC LIMIT 1);

ตัวอย่าง

1. สร้างตารางและข้อมูล 13 แถว

mysql> create table previousAndNextRecordDemo (
    -> Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> Name varchar(30)
    -> );

mysql> insert into previousAndNextRecordDemo(Name) values
    -> ('John'),('Sam'),('Carol'),('Bob'),('Larry'),('David'),
    -> ('Ramit'),('Maxwell'),('Mike'),('Robert'),('Chris'),('James'),('Jace');

2. หาแถวก่อนหน้าและถัดไปของ ID = 8

mysql> (SELECT * FROM previousAndNextRecordDemo WHERE Id > 8 ORDER BY Id ASC LIMIT 1)
    -> UNION
    -> (SELECT * FROM previousAndNextRecordDemo WHERE Id < 8 ORDER BY Id DESC LIMIT 1);
+----+-------+
| Id | Name  |
+----+-------+
| 9  | Mike  |
| 7  | Ramit |
+----+-------+

การทำงาน

  • Subquery แรก: Id > 8 ORDER BY Id ASC LIMIT 1 → หาค่าต่ำสุดที่ > 8 (ถัดไป)
  • Subquery ที่สอง: Id < 8 ORDER BY Id DESC LIMIT 1 → หาค่าสูงสุดที่ < 8 (ก่อนหน้า)
  • UNION รวมผลลัพธ์ (ลบซ้ำอัตโนมัติ)

MySQL 8.0+ ใช้ Window Functions (มีประสิทธิภาพมากกว่า)

WITH ranked AS (
    SELECT *,
           LAG(Name) OVER (ORDER BY Id) AS prev_name,
           LEAD(Name) OVER (ORDER BY Id) AS next_name
    FROM previousAndNextRecordDemo
)
SELECT Id, Name, prev_name, next_name
FROM ranked
WHERE Id = 8;

กรณีต้องการรวม ID ปัจจุบันด้วย

(SELECT * FROM previousAndNextRecordDemo WHERE Id >= 8 ORDER BY Id ASC LIMIT 2)
UNION
(SELECT * FROM previousAndNextRecordDemo WHERE Id <= 8 ORDER BY Id DESC LIMIT 2);

กรณีข้อมูลไม่เรียงตาม ID (ใช้ ORDER BY column)

(SELECT * FROM yourTable WHERE sort_col > 'target' ORDER BY sort_col ASC LIMIT 1)
UNION
(SELECT * FROM yourTable WHERE sort_col < 'target' ORDER BY sort_col DESC LIMIT 1);