Ko'pincha bizga shunday natija kerak bo'ladi: har bir qator o'z joyida qolsin, lekin qo'shimcha hisob-kitob (masalan, tartib raqami) ham ko'rinsin. Aynan shu vazifani oyna funksiyalari (window functions) bajaradi.
Bu darsda biz mahsulotlar jadvali bilan ishlaymiz:
| id | nomi | kategoriya | narx | ombor |
|---|---|---|---|---|
| 1 | Telefon | Elektronika | 5000000 | 10 |
| 2 | Noutbuk | Elektronika | 12000000 | 5 |
| 3 | Quloqchin | Elektronika | 300000 | 50 |
| 4 | Kitob | Kitoblar | 50000 | 100 |
| 5 | Daftar | Kanstovar | 8000 | 200 |
| 6 | Ruchka | Kanstovar | 3000 | 500 |
| 7 | Stol | Mebel | 800000 | 15 |
| 8 | Stul | Mebel | 250000 | 40 |
Avvalgi darslarda COUNT, SUM, AVG kabi agregat funksiyalar bilan tanishdik. Ular bir nechta qatorni bitta qatorga yig'adi. Masalan, SELECT COUNT(*) FROM mahsulotlar; bizga atigi bitta son qaytaradi.
Oyna funksiyalari esa qatorlarni yig'maydi — har bir qator o'z joyida qoladi, lekin yoniga qo'shimcha ustun (masalan, tartib raqami) qo'shiladi. Mana shu eng muhim farq.
ROW_NUMBER() funksiyasi har bir qatorga 1, 2, 3, ... tartibida ketma-ket raqam beradi. Bu raqam qaysi tartibda berilishini esa OVER (ORDER BY ...) ichida ko'rsatamiz:
SELECT nomi, ROW_NUMBER() OVER (ORDER BY narx) FROM mahsulotlar ORDER BY narx;Bu so'rov mahsulotlarni narxi bo'yicha eng arzonidan boshlab raqamlaydi:
Ruchka|1
Daftar|2
Kitob|3
Stul|4
Quloqchin|5
Stol|6
Telefon|7
Noutbuk|8E'tibor bering: OVER so'zidan oldin funksiya turadi (ROW_NUMBER()), OVER ichidagi ORDER BY esa raqamlash tartibini belgilaydi.
Eslatma:
OVER (...)ichidagiORDER BYraqamlash tartibini belgilaydi, so'rov oxiridagiORDER BYesa natijaning ekranga chiqish tartibini belgilaydi. Bir xil tartib chiqishi uchun ko'pincha ikkalasini ham bir xil yozamiz.
Agar eng qimmat mahsulotdan boshlab raqamlamoqchi bo'lsak, OVER ichida DESC (kamayish tartibi) ishlatamiz:
SELECT nomi, ROW_NUMBER() OVER (ORDER BY narx DESC) FROM mahsulotlar ORDER BY narx DESC;Endi 1-raqam eng qimmat mahsulotga (Noutbuk) tegishli bo'ladi:
Noutbuk|1
Telefon|2
Stol|3
Quloqchin|4
Stul|5
Kitob|6
Daftar|7
Ruchka|8ROW_NUMBER() ga o'xshash yana bir funksiya bor — RANK(). U ham qatorlarni raqamlaydi, lekin bir xil qiymatlarga bir xil raqam beradi. Masalan, ikkita mahsulotning narxi teng bo'lsa, ROW_NUMBER() ularga 3 va 4 beradi, RANK() esa ikkalasiga ham 3 beradi (keyingi qator esa 5 dan davom etadi). Sintaksisi xuddi shunday:
SELECT nomi, RANK() OVER (ORDER BY narx DESC) FROM mahsulotlar ORDER BY narx DESC;Bizning jadvalimizda barcha narxlar har xil bo'lgani uchun bu yerda RANK() natijasi ROW_NUMBER() bilan bir xil chiqadi. Hozircha shuni bilsangiz yetarli — asosiy e'tiborni ROW_NUMBER() ga qarating.
Pastdagi kod oynasida mahsulotlar jadvali allaqachon yaratilgan va to'ldirilgan. Sizning vazifangiz — mahsulotlarni narxi bo'yicha kamayish tartibida ROW_NUMBER() bilan raqamlab, har bir mahsulotning nomi va tartib raqamini chiqarish.