Saytdan foydalanishda muammoga duch kelsangiz, qo'llab-quvvatlash xizmatiga murojaat qiling: @fast_support_admin
Window funksiyalar3 daqiqa o'qish

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

studentscore
Aziz95
Malika90
Sardor90
Nodira85

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;
studentscorerow_numberrankdense_rank
Aziz95111
Malika90222
Sardor90322
Nodira85443
  • 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:

To'g'ri yechim
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

Noto'g'ri yondashuv
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_NUMBER 1-2-3-4, RANK 1-2-2-4, DENSE_RANK 1-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.

Telegram'da muhokama qilish