เทคนิคการ Query ข้อมูลล่าสุดในแต่ละกลุ่ม (ตอนที่ 1)
สิ่งที่ผมต้องการจากตารางด้านล่างคือ ผมต้องการ Query เอาข้อมูลแต่ละ repair_id ที่ status ล่าสุด (รายการล่าสุดคือรายการที่ id มากที่สุด)
จริงๆที่ผมคิดไว้แต่แรกคือการ Query ข้อมูลโดยเรียงลำดับเอา id ล่าสุดไว้ก่อน เสร็จแล้วค่อยเอาไป GROUP BY ซึ่งจะได้ข้อมูลแถวแรกที่มากที่สุดออกมาออกมา
แต่ผลลัพท์กลับไม่เป็นดังคาดเนื่องจากคำสั่ง GROUP BY จะมีการเรียงลำดับข้อมูลจากน้อยไปมากทุกครั้งที่เรียกใช้ ทำให้ข้อมูลที่เรียงลำดับไว้แต่แรกไม่สามารถทำงานได้ตามที่ต้องการ วิธีที่ถูกต้อง
วิธีแรก ใช้ SUBQUERY
ผลลัพท์ของ Query ด้านบน อธิบาย Query
ขั้นตอนแรกจะทำบรรทัดนี้ก่อน คือเลือกตาราง table_name และวนลูปทีละแถว
ขั้นตอนที่สอง ในแต่ละแถว จะทำการ Query หารายการที่ repair_id เดียวกันแต่เป็น id ล่าสุด หรือ id ที่มากที่สุด ด้วย MAX(id)
สุดท้าย คำสั่ง SELECT เลือกข้อมูลที่ต้องการมาแสดง
วิธีที่สอง ใช้การ JOIN
อธิบาย Query
ขั้นตอนแรกจะทำคำสั่งใน SUBQUERY ก่อน ได้ผลลพัท์ออกมารอไว้
ถัดมาจะทำคำสั่ง FORM และวนลูปทีละแถวและจับคู่กับข้อมูลจาก SUBQUERY ได้ผลลัพท์ที่ T
และเลือกข้อมูลที่ต้องการด้วยเงื่อนไขในการ JOIN คือ
ก็จะได้ผลลัพท์ออกมาเหมือนกัน
สำหรับทั้งสองวิธีข้างต้น วิธีไหนจะมีประสิทธิภาพมากกว่ากันติดตามต่อที่ ตอนที่ 2 เลยครับ
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 เลยครับ