ใน MySQL ตั้งแต่เวอร์ชั่น 8.0 เป็นต้นไป ถ้าต้องการดึงค่าแรกและค่าสุดท้ายในกรุ๊ปนั้น ๆ ออกมา สามารถใช้ Function
- FIRST_VALUE()
FIRST_VALUE(expr) [null_treatment] over_clause
Returns the value of expr from the first row of the window frame. - LAST_VALUE()
LAST_VALUE(expr) [null_treatment] over_clause
Returns the value of expr from the last row of the window frame.
ตัวอย่างการใช้งาน
โจทย์ มีข้อมูล CKD Stage (สมมุติ) เรียงตามรายปีงบประมาณ ถ้าต้องการทราบ Stage แรกและสุดท้ายที่ตรวจพบในรายนั้น ๆ หาได้จาก
เริ่มต้นคือสร้างตารางทดสอบ
CREATE TABLE ckdstage(vn INT(11) AUTO_INCREMENT,
hn VARCHAR(50) NOT NULL,
fiscal_year INT NOT NULL,
stage INT(1) NOT NULL,
PRIMARY KEY(vn)
);
INSERT INTO ckdstage(vn,hn,fiscal_year,stage)
VALUES
(NULL,'1945',2016, 4),
(NULL,'1945',2017, 3),
(NULL,'1945',2018, 5),
(NULL,'1945',2019, 3),
(NULL,'2311',2016, 4),
(NULL,'2311',2017, 5),
(NULL,'2311',2018, 3),
(NULL,'2311',2019, 2);
ข้อมูลที่ได้จะเป็นตามนี้ ถ้ามองด้วยสายตาค่าที่เราต้องการจะตามที่ลูกศรชี้

หาผลลัพธ์ตามโจทย์
SELECT
hn,
fiscal_year,
FIRST_VALUE(stage) OVER (
PARTITION BY hn
ORDER BY fiscal_year
) first_stage,
LAST_VALUE(stage) OVER (
PARTITION BY hn
ORDER BY fiscal_year
RANGE BETWEEN
UNBOUNDED PRECEDING AND
UNBOUNDED FOLLOWING
) last_stage
FROM ckdstage;

จะเห็นได้ว่าผลลัพธ์ทีได้จะดึงค่าแรกสุดและค่าสุดท้ายตามกรุ๊ปของคอลัมภ์ hn แต่ข่าวร้ายก็คือฟังก์ชั่นนี้ไม่มีให้ใช้ใน MySQL เวอร์ชั่นเก่า 55555 ซึ่งก็สามารถแก้ปัญหาโดยการจำลองฟังก์ชั่น First(), Last() ขึ้นมาใช้งานเอง ตัวอย่าง
SELECT
t1.hn,
GROUP_CONCAT(t1.stage ORDER BY t1.vn ASC) AS stagelist_asc,
GROUP_CONCAT(t1.stage ORDER BY t1.vn DESC) AS stagelist_desc,
SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t1.stage ORDER BY t1.vn ASC), ',', 1) , ',' , -1) AS first_stage,
SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t1.stage ORDER BY t1.vn DESC), ',', 1) , ',' , -1) AS last_stage
FROM ckdstage AS t1
GROUP BY t1.hn

จบปิ๊ง !! ^__^
ป.ล.

