เทคนิคการ Query ข้อมูลล่าสุดในแต่ละกลุ่ม (ตอนที่ 1)

สิ่งที่ผมต้องการจากตารางด้านล่างคือ ผมต้องการ Query เอาข้อมูลแต่ละ repair_id ที่ status ล่าสุด (รายการล่าสุดคือรายการที่ id มากที่สุด)
จริงๆที่ผมคิดไว้แต่แรกคือการ Query ข้อมูลโดยเรียงลำดับเอา id ล่าสุดไว้ก่อน เสร็จแล้วค่อยเอาไป GROUP BY ซึ่งจะได้ข้อมูลแถวแรกที่มากที่สุดออกมาออกมา
SELECT * FROM (
  SELECT `id`,`status`,`repair_id` FROM `table_name` ORDER BY `id` DESC
) AS Q GROUP BY `repair_id`

แต่ผลลัพท์กลับไม่เป็นดังคาดเนื่องจากคำสั่ง GROUP BY จะมีการเรียงลำดับข้อมูลจากน้อยไปมากทุกครั้งที่เรียกใช้ ทำให้ข้อมูลที่เรียงลำดับไว้แต่แรกไม่สามารถทำงานได้ตามที่ต้องการ
วิธีที่ถูกต้อง
วิธีแรก ใช้ SUBQUERY
SELECT `id`,`status`,`repair_id` 
FROM `table_name` AS S 
WHERE S.`id`=(
  SELECT MAX(`id`)
  FROM `table_name`
  WHERE `repair_id`=S.`repair_id`
)

ผลลัพท์ของ Query ด้านบน
อธิบาย Query
ขั้นตอนแรกจะทำบรรทัดนี้ก่อน คือเลือกตาราง table_name และวนลูปทีละแถว
FROM `table_name` AS S
ขั้นตอนที่สอง ในแต่ละแถว จะทำการ Query หารายการที่ repair_id เดียวกันแต่เป็น id ล่าสุด หรือ id ที่มากที่สุด ด้วย MAX(id)
WHERE S.`id`=(SELECT MAX(`id`) FROM `table_name` WHERE `repair_id`=S.`repair_id`)
สุดท้าย คำสั่ง SELECT เลือกข้อมูลที่ต้องการมาแสดง

วิธีที่สอง ใช้การ JOIN
SELECT S.`id`,S.`status`,S.`repair_id`
FROM `table_name` AS S
JOIN (
  SELECT `repair_id`, max(`id`) AS `max_id`
  FROM `table_name`
  GROUP BY `repair_id`
) AS T ON T.`repair_id`=S.`repair_id` AND S.`id`=T.`max_id`

อธิบาย Query
ขั้นตอนแรกจะทำคำสั่งใน SUBQUERY ก่อน ได้ผลลพัท์ออกมารอไว้
SELECT `repair_id`, max(`id`) AS `max_id` FROM `table_name` GROUP BY `repair_id`
ถัดมาจะทำคำสั่ง FORM และวนลูปทีละแถวและจับคู่กับข้อมูลจาก SUBQUERY ได้ผลลัพท์ที่ T
FROM .... JOIN(...) AS T
และเลือกข้อมูลที่ต้องการด้วยเงื่อนไขในการ JOIN คือ
T.`repair_id`=S.`repair_id` AND S.`id`=T.`max_id`
ก็จะได้ผลลัพท์ออกมาเหมือนกัน

สำหรับทั้งสองวิธีข้างต้น วิธีไหนจะมีประสิทธิภาพมากกว่ากันติดตามต่อที่ ตอนที่ 2 เลยครับ

เรื่องที่เกี่ยวข้อง

^