หนึ่งในฟีเจอร์ที่ทรงพลังของ SQL โดยเฉพาะใน PostgreSQL ก็คือ Window Functions ซึ่งช่วยให้เราสามารถทำการคำนวณข้ามแถว (rows) ได้โดยไม่ต้องใช้ Subquery ซับซ้อน บทความนี้จะเจาะลึก Window Functions ยอดนิยม ได้แก่ ROW_NUMBER(), RANK(), LAG(), และ LEAD()
Window Function คืออะไร?
Window Function เป็นฟังก์ชันที่ทำงานบน “หน้าต่างข้อมูล” (window of rows) โดยใช้คำสั่ง OVER()
กำหนดช่วงข้อมูลที่ต้องการ ต่างจาก Aggregate Function ทั่วไปตรงที่ Window Function จะไม่ลดจำนวนแถว แต่จะคืนค่าตามแต่ละแถว
SELECT column, ROW_NUMBER() OVER(ORDER BY column) AS row_num FROM table;
ตัวอย่างตารางข้อมูล
CREATE TABLE sales ( id SERIAL PRIMARY KEY, employee VARCHAR(50), region VARCHAR(50), amount DECIMAL(10,2) ); INSERT INTO sales (employee, region, amount) VALUES ('Alice', 'North', 500), ('Bob', 'North', 700), ('Charlie', 'South', 600), ('David', 'South', 800), ('Eve', 'North', 900);
1. ROW_NUMBER()
ROW_NUMBER() ใช้กำหนดลำดับแถวตามเงื่อนไขที่กำหนด เช่น การจัดอันดับยอดขายของพนักงาน
SELECT employee, amount, ROW_NUMBER() OVER(ORDER BY amount DESC) AS row_num FROM sales;
2. RANK()
RANK() คล้ายกับ ROW_NUMBER() แต่จะให้ลำดับซ้ำเมื่อค่ามีค่าเท่ากัน และข้ามลำดับถัดไป เช่น ถ้ามีสองแถวที่อันดับ 1 แถวถัดไปจะเป็นอันดับ 3
SELECT employee, amount, RANK() OVER(ORDER BY amount DESC) AS rank FROM sales;
3. LAG()
LAG() ใช้ดึงค่าจาก “แถวก่อนหน้า” ในหน้าต่างข้อมูล เหมาะสำหรับเปรียบเทียบค่าระหว่างปัจจุบันกับค่าเดิม
SELECT employee, amount, LAG(amount, 1) OVER(ORDER BY amount) AS prev_amount FROM sales;
4. LEAD()
LEAD() ใช้ดึงค่าจาก “แถวถัดไป” ในหน้าต่างข้อมูล เหมาะกับการเปรียบเทียบข้อมูลกับค่าที่จะเกิดขึ้นในอนาคต
SELECT employee, amount, LEAD(amount, 1) OVER(ORDER BY amount) AS next_amount FROM sales;
การใช้ PARTITION BY
Window Functions สามารถใช้ PARTITION BY
เพื่อแบ่งกลุ่มข้อมูล เช่น จัดอันดับยอดขายตาม Region
SELECT employee, region, amount, RANK() OVER(PARTITION BY region ORDER BY amount DESC) AS region_rank FROM sales;
สรุปการใช้งาน Window Functions
- ROW_NUMBER() → ลำดับต่อเนื่อง
- RANK() → ลำดับพร้อมการข้ามเมื่อมีค่าเท่ากัน
- LAG() → ดึงค่าจากแถวก่อนหน้า
- LEAD() → ดึงค่าจากแถวถัดไป
- PARTITION BY → จัดอันดับภายในกลุ่ม
SEO Keywords
SQL Window Functions,ROW_NUMBER SQL,RANK SQL,LAG SQL,LEAD SQL,PostgreSQL Window Functions,การใช้ Window Functions,สอน SQL ขั้นสูง,SQL OVER PARTITION BY