উইন্ডো ফাংশন GROUP BY যেভাবে করে সেভাবে সারিগুলোকে একটিতে গুটিয়ে না ফেলেই একদল সম্পর্কিত সারি জুড়ে গণনা করে। প্রতিটি ইনপুট সারি আউটপুটে তার জায়গা ধরে রাখে — ফাংশনটি শুধু তার পাশে একটি গণনা করা মান যোগ করে।
একটি উইন্ডোর ভেতরে প্রতিটি সারিকে একটি অনন্য, ক্রমিক সংখ্যা দেয়।
ROW_NUMBER() OVER (ORDER BY column);SELECT name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS rank
FROM Employee;সাধারণ ভুল
নম্বরিং পুরো ফলাফল জুড়ে না চলে প্রতিটি গ্রুপ থেকে আবার শুরু হওয়া উচিত হলে PARTITION BY দিতে ভুলে যাওয়া।
সারিগুলোকে র্যাংক দেয়, টাইকে একই র্যাংক দেয় আর পরের সংখ্যা বাদ দেয়।
RANK() OVER (ORDER BY column);SELECT name, salary,
RANK() OVER (ORDER BY salary DESC) AS rank
FROM Employee;সাধারণ ভুল
টাই থাকলে RANK ধারাবাহিক সংখ্যা তৈরি করবে বলে আশা করা — এটি ইচ্ছাকৃতভাবেই করে না।
RANK-এর মতোই, কিন্তু টাই-এর পর কখনো কোনো সংখ্যা বাদ দেয় না।
DENSE_RANK() OVER (ORDER BY column);SELECT name, salary,
DENSE_RANK() OVER (ORDER BY salary DESC) AS rank
FROM Employee;সাধারণ ভুল
যখন আসলে ব্যবধানসহ স্ট্যান্ডার্ড প্রতিযোগিতার র্যাংকিং (অর্থাৎ RANK) দরকার ছিল, তখন DENSE_RANK ব্যবহার করা।
সারিগুলোকে একটি নির্দিষ্ট সংখ্যক প্রায়-সমান গ্রুপে ভাগ করে।
NTILE(n) OVER (ORDER BY column);SELECT name, salary,
NTILE(4) OVER (ORDER BY salary DESC) AS quartile
FROM Employee;সাধারণ ভুল
সারির সংখ্যা n দিয়ে সমানভাবে ভাগ না হলেও প্রতিটি গ্রুপের আকার ঠিক সমান হবে বলে ধরে নেওয়া।
একটি সেলফ-জয়েন ছাড়াই আগের বা পরের সারি থেকে একটি মান পড়ে।
LAG(column) OVER (ORDER BY column);
LEAD(column) OVER (ORDER BY column);SELECT name, salary,
LAG(salary) OVER (ORDER BY hire_date) AS prev_salary
FROM Employee;সাধারণ ভুল
OVER()-এর ভেতরে ORDER BY দিতে ভুলে যাওয়া, যা "আগের" আর "পরের" সারিকে অনির্ধারিত করে দেয়।
উইন্ডো ফাংশন এই অংশের আরও উন্নত টুলগুলোর একটি — পরের পাঠে আরেকটি আলোচনা হবে: সাবকোয়েরি, একটি কোয়েরির ভেতরে বসানো আরেকটি কোয়েরি।