ROW_NUMBER, RANK va DENSE_RANK farqi
Uchala window funksiya ham qatorlarni raqamlaydi, farq teng qiymatlarda chiqadi. Reyting, top-N va dublikatlarni o'chirish uchun qaysi biri kerakligini ko'ramiz.
Reyting tuzish, har bir guruhdan top-3 ni olish, dublikatlarni tozalash — bularning hammasi qatorlarni raqamlashdan boshlanadi. PostgreSQL da buning uchun uchta window funksiya bor va ular faqat teng qiymatlar uchraganda farq qiladi.
Jadval: scores
| student | score |
|---|---|
| Aziz | 95 |
| Malika | 90 |
| Sardor | 90 |
| Nodira | 85 |
Malika va Sardor bir xil ball olgan.
Uchalasini yonma-yon solishtiramiz
SELECT student, score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS row_number,
RANK() OVER (ORDER BY score DESC) AS rank,
DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank
FROM scores;| student | score | row_number | rank | dense_rank |
|---|---|---|---|---|
| Aziz | 95 | 1 | 1 | 1 |
| Malika | 90 | 2 | 2 | 2 |
| Sardor | 90 | 3 | 2 | 2 |
| Nodira | 85 | 4 | 4 | 3 |
ROW_NUMBER— tenglikka qaramaydi, har doim 1, 2, 3, 4. Teng qatorlardan qaysi biri oldin turishi kafolatlanmagan.RANK— tenglarga bir xil o'rin beradi va keyingi o'rinni "sakrab o'tadi": 1, 2, 2, 4 (sportdagi kabi).DENSE_RANK— tenglarga bir xil o'rin, lekin bo'shliqsiz: 1, 2, 2, 3.
Qaysi birini qachon ishlatish kerak
- Har bir guruhdan aniq bitta qator kerak (oxirgi buyurtma, dublikatdan bittasi) —
ROW_NUMBER. - Musobaqa natijalari, "o'rin" tushunchasi —
RANK. - "Ikkinchi eng katta maosh", "top-3 xil narx" —
DENSE_RANK.
Guruh ichida raqamlash: PARTITION BY
Har bir bo'lim ichida eng ko'p maosh oladigan xodim:
SELECT department, name, salary
FROM (
SELECT department, name, salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn
FROM employees
) t
WHERE rn = 1;PARTITION BY raqamlashni har bir bo'lim uchun 1 dan qayta boshlaydi.
Ko'p uchraydigan xato: window natijasini WHERE da ishlatish
SELECT name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn
FROM employees
WHERE rn <= 3;Xato: column "rn" does not exist. Window funksiyalar WHERE dan keyin hisoblanadi, shuning uchun ularni yuqoridagidek subquery yoki CTE ichiga olib, tashqarida filtrlash kerak.
Ikkinchi xato: tenglikda ROW_NUMBER bilan top-N
"Eng yaxshi 2 talaba"ni ROW_NUMBER() <= 2 bilan olsak, Malika va Sardordan bittasi tasodifiy tushib qoladi. Vazifa tenglarni ham qo'shishni talab qilsa — RANK() <= 2 yoki DENSE_RANK() <= 2. ROW_NUMBER ishlatilsa, ORDER BY ga qo'shimcha ustun qo'shib (masalan, score DESC, student) natijani barqaror qiling.
Xulosa
- Farq faqat teng qiymatlarda:
ROW_NUMBER1-2-3-4,RANK1-2-2-4,DENSE_RANK1-2-2-3. PARTITION BY— har bir guruh ichida alohida raqamlash.- Window natijasini filtrlash uchun subquery yoki CTE kerak.
Endi o'zingiz yechib ko'ring
O'rganganingizni mustahkamlang — so'rovingiz brauzerda darhol tekshiriladi.
