ในโลกของการวิเคราะห์ข้อมูลเชิงลึก (Advanced Data Analytics) ข้อมูลส่วนใหญ่ไม่ได้ถูกพิจารณาแบบโดดเดี่ยว แต่เป็นชุดของเหตุการณ์ที่เกิดขึ้นตามลำดับเวลา (Time Series) หรือขั้นตอนการดำเนินงาน การทำความเข้าใจว่าค่า ณ จุดใดจุดหนึ่งมีความสัมพันธ์อย่างไรกับสิ่งที่เกิดขึ้นก่อนหน้า (Previous) และหลังจากนั้น (Next) จึงเป็นหัวใจสำคัญในการค้นพบรูปแบบ (Pattern) การระบุแนวโน้ม (Trend) หรือการตรวจจับความผิดปกติ (Anomaly Detection) หากเราต้องการเปรียบเทียบยอดขายวันนี้กับเมื่อวาน หรือดูว่าสถานะของผู้ใช้มีการเปลี่ยนแปลงอย่างไรจากรอบล่าสุด การใช้ฟังก์ชัน SQL พื้นฐานอาจไม่เพียงพอ
ทำความรู้จักกับ Window Functions: LEAD() และ LAG()
ฟังก์ชัน Window Function เช่น LEAD() และ LAG() คือเครื่องมือทรงพลังระดับ Senior Architect ใน PostgreSQL ที่ช่วยให้เราสามารถ “มองข้าม” ข้อมูลไปที่แถวก่อนหน้า (Lag) หรือแถวถัดไป (Lead) ได้อย่างมีประสิทธิภาพ โดยไม่ต้องใช้ Self-Join ที่ซับซ้อนและกินทรัพยากรมากนัก
แนวคิดหลักคือการกำหนด ‘หน้าต่าง’ ของข้อมูล (Window Partition) ซึ่งเป็นการแบ่งชุดข้อมูลออกเป็นกลุ่มย่อย ๆ ตามเงื่อนไขที่กำหนด (เช่น แบ่งตาม Product ID) และจากนั้นจึงระบุว่าเราต้องการค่าที่ห่างออกไปกี่แถว (Offset) จากแถวปัจจุบัน
หลักการทำงานของ LEAD() และ LAG()
LAG(column, offset, default_value): จะดึงค่าจากคอลัมน์ที่กำหนดในแถวก่อนหน้าตามจำนวนoffsetที่ระบุ หากไม่มีค่าในแถวก่อนหน้า จะใช้ค่าdefault_valueแทนLEAD(column, offset, default_value): จะทำหน้าที่ตรงกันข้าม คือการดึงค่าจากแถวถัดไปตามจำนวนoffsetที่กำหนด
การใช้งานที่สมบูรณ์จะต้องระบุ OVER (PARTITION BY ... ORDER BY ...) เสมอ เพื่อกำหนดขอบเขตและลำดับของการเปรียบเทียบ
ตัวอย่างการใช้งานจริงใน PostgreSQL
สมมติว่าเรามีตารางข้อมูลยอดขายรายวัน (sales_data) และต้องการเปรียบเทียบยอดขายของวันนี้กับยอดขายของเมื่อวานและวันพรุ่งนี้
SQL
-- 1. สร้างตารางจำลอง (Setup) และใส่ข้อมูลตัวอย่าง
CREATE TABLE sales_data (
sale_date DATE,
product VARCHAR(50),
sale_amount NUMERIC
);
INSERT INTO sales_data (sale_date, product, sale_amount) VALUES
('2023-10-01', 'A', 100.00),
('2023-10-02', 'A', 150.00),
('2023-10-03', 'A', 120.00),
('2023-10-01', 'B', 50.00),
('2023-10-02', 'B', 70.00);
-- 2. ใช้ LAG() และ LEAD() เพื่อเปรียบเทียบ
SELECT
sale_date,
product,
sale_amount,
-- ดึงค่าก่อนหน้า (LAG): ยอดขายของเมื่อวาน
LAG(sale_amount, 1) OVER (PARTITION BY product ORDER BY sale_date) AS previous_day_sale,
-- ดึงค่าถัดไป (LEAD): ยอดขายของวันพรุ่งนี้
LEAD(sale_amount, 1) OVER (PARTITION BY product ORDER BY sale_date) AS next_day_sale
FROM
sales_data
ORDER BY
product, sale_date;
คำอธิบายโค้ด:
PARTITION BY product: กำหนดให้การคำนวณเกิดขึ้นแยกกันตามสินค้าแต่ละชนิด (A และ B)ORDER BY sale_date: กำหนดลำดับการเปรียบเทียบตามวันที่LAG(sale_amount, 1): ดึงค่าsale_amountจากแถวก่อนหน้า 1 แถวLEAD(sale_amount, 1): ดึงค่าsale_amountจากแถวถัดไป 1 แถว
บทสรุป: การประยุกต์ใช้ในงานจริง
การใช้ LEAD() และ LAG() ไม่ได้จำกัดอยู่แค่การเปรียบเทียบยอดขายเท่านั้น แต่ยังสามารถนำไปใช้ในการคำนวณอัตราการเปลี่ยนแปลง (Rate of Change), การหาความแตกต่างของสถานะ (State Transition) ในระบบ Workflow, หรือการวิเคราะห์ความแตกต่างของค่าทางสถิติระหว่างช่วงเวลาได้อย่างแม่นยำและมีประสิทธิภาพสูง การทำความเข้าใจ Window Functions เหล่านี้ถือเป็นทักษะสำคัญสำหรับ Data Engineer และ Data Analyst ระดับ Senior ที่ต้องการเขียน Query ที่ซับซ้อนและมีประสิทธิภาพใน PostgreSQL