OVER() — bu, SQL-ə deyir ki, window funksiyasını hansı sətrlər üzərində tətbiq etsin. Başqa cür desək, bu, window funksiyası üçün "pəncərəni" müəyyən edən üsuldur. Təsəvvür elə, bir otaq dolu adam var və biz hər kvadrat metrə neçə adam düşdüyünü saymaq istəyirik. OVER() göstərir ki, otağın hansı hissəsində diqqətimizi cəmləyirik. Yəni, hansı sətrlər üzərində funksiya işləyəcək, onu təyin edir.
OVER() operatoru yalnız window funksiyaları ilə istifadə olunur və bir və ya bir neçə cədvəldə sətrlər üzərində əməliyyat aparmağa imkan verir, amma data qruplaşdırılmır.
Sintaksis:
window_funksiyasi() OVER (
[PARTITION BY ...]
[ORDER BY ...]
[ROWS/RANGE ...]
)
Burada:
PARTITION BY— datanı məntiqi qruplara bölürORDER BY— hər qrupun içində sətrlərin sırasını təyin edirROWS/RANGE— "pəncərənin" ölçüsünü dəqiqləşdirir (məsələn, cari sətr + 1 növbəti)
Nümunə: OVER() parametrlərsiz
OVER() əlavə parametrlərsiz istifadə olunanda, ondan əvvəlki funksiya bütün data set-ə tətbiq olunur.
SELECT
employee_id,
salary,
ROW_NUMBER() OVER () AS row_num -- ROW_NUMBER() bütün nəticə sətrlərinə tətbiq olunacaq
FROM employees;
Nə baş verir?
ROW_NUMBER()hər sətrə unikal nömrə verir.OVER()içində heç bir parametr olmadığı üçün,employeescədvəlindəki bütün sətrlər bir yerdə işlənir.
Nəticə:
| employee_id | salary | row_num |
|---|---|---|
| 1 | 50000 | 1 |
| 2 | 60000 | 2 |
| 3 | 55000 | 3 |
Qruplar üçün PARTITION BY istifadəsi
Super, indi təsəvvür elə ki, bizə bütün şirkət üzrə yox, hər şöbə daxilində işçilərin nömrələnməsi maraqlıdır. Burada PARTITION BY köməyə gəlir.
OVER() içində PARTITION BY datanı qruplara (və ya "bölmələrə") ayırır. Hər qrup üçün funksiya ayrıca hesablanır. Yəni, əgər ROW_NUMBER() ofisiant olsaydı, hər "stol" (bölmə) üçün nömrələməyə sıfırdan başlayardı.
Nümunə: PARTITION BY istifadə edirik
SELECT
department_id,
employee_id,
salary,
ROW_NUMBER() OVER (PARTITION BY department_id) AS row_num
FROM employees;
Nə baş verir?
employeescədvəlindən datalardepartment_iddəyərinə görə qruplaşdırılır.- Hər qrupda sətrlərə
ROW_NUMBER()ilə sıra nömrəsi verilir.
Nəticə:
| department_id | employee_id | salary | row_num |
|---|---|---|---|
| 1 | 1 | 50000 | 1 |
| 1 | 3 | 55000 | 2 |
| 2 | 2 | 60000 | 1 |
Sıra üçün ORDER BY istifadəsi
İndi isə bir az struktur əlavə edək. Təsəvvür elə, bizə sadəcə nömrələmək yox, bunu müəyyən qaydada etmək lazımdır, məsələn, ən yüksək maaşdan başlayaraq. Bu iş üçün ORDER BY istifadə olunur.
ORDER BY window funksiyasının sətrləri hansı qaydada işləyəcəyini təyin edir.
Nümunə: OVER() içində ORDER BY istifadə edirik
SELECT
department_id,
employee_id,
salary,
RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank
FROM employees;
Nə baş verir?
- Data qruplara bölünür (
PARTITION BY department_id). - Hər qrupda sətrlər maaşa görə azalan sırada düzülür (
ORDER BY salary DESC). - Hər sətrə sıralama nəzərə alınaraq rank verilir.
Nəticə:
| department_id | employee_id | salary | rank |
|---|---|---|---|
| 1 | 3 | 55000 | 1 |
| 1 | 1 | 50000 | 2 |
| 2 | 2 | 60000 | 1 |
Window funksiyalarının kombinasiyası
SQL-də bir sorğuda bir neçə window funksiyasını istifadə etmək olar və hər biri öz qaydalarına görə işləyə bilər. Bu, bir otaqda eyni anda həm musiqi çalır, həm də adamlar sayılır — hər proses müstəqildir!
Nümunə: bir neçə window funksiyası
SELECT
department_id,
employee_id,
salary,
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num,
AVG(salary) OVER (PARTITION BY department_id) AS avg_salary
FROM employees;
Nə baş verir?
ROW_NUMBER()hər qrupda sətrləri maaşa görə azalan sırada nömrələyir.AVG()hər qrupda orta maaşı hesablayır.
Nəticə:
| department_id | employee_id | salary | row_num | avg_salary |
|---|---|---|---|---|
| 1 | 3 | 55000 | 1 | 52500 |
| 1 | 1 | 50000 | 2 | 52500 |
| 2 | 2 | 60000 | 1 | 60000 |
Real həyatdan nümunələr
OVER() ilə window funksiyaları bir çox real situasiyada istifadə olunur. Budur bir neçə nümunə:
- Satış analitikası: hər kateqoriyada məhsulların satış sayına görə sıralanması.
- Reytinqlər: hər qrupda tələbələrin orta bala görə mövqeyinin müəyyən olunması.
- Zaman sıraları: zaman kəsiyində satışların yığılan cəmi.
Satış analitikasından nümunə:
SELECT
category_id,
product_id,
product_name,
SUM(sales) OVER (PARTITION BY category_id ORDER BY sales DESC) AS cumulative_sales
FROM products;
Window funksiyaları ilə işləyərkən yayılmış səhvlər
PARTITION BYolmaması
Əgər PARTITION BY istifadə etmirsənsə, window funksiyası bütün cədvələ tətbiq olunur. Bu, gözlənilməz nəticələrə səbəb ola bilər, xüsusən də qruplara bölünmə gözləyirdinsə.
💡 Mütləq göstər ki, cədvəl necə bölünməlidir — məsələn, istifadəçiyə, sifarişə və ya kateqoriyaya görə.
ORDER BYiçində yanlış data tipləri
Window funksiyası içində ORDER BY data tiplərinə həssasdır. Əgər tarix sahəsini VARCHAR kimi saxlayıb sıralayırsansa, nəticə əlifba sırası ilə ola bilər, xronoloji yox.
💡 Belə sahələri sıralamadan əvvəl düzgün tipə (DATE, INTEGER və s.) çevir.
ROWS BETWEENyanlış istifadəsi
Default olaraq window funksiyaları ROWS BETWEEN ilə müəyyən olunan çərçivə ilə işləyir. Əgər çərçivəni açıq göstərməsən, RANGE davranışı tətbiq oluna bilər və bu, gözlədiyindən daha çox sətr qaytara bilər.
💡 Dəqiq nəzarət üçün ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW istifadə et, əgər başlanğıcdan cari sətrə qədər yığılan nəticə lazımdırsa.
NULLilə düzgün işləməmək
Window funksiyaları NULL dəyərləri fərqli cür işləyə bilər. Məsələn, RANK() və DENSE_RANK() NULL-u ayrıca dəyər kimi sayır və ona ayrıca rank verir.
💡 ORDER BY içində NULLS LAST və ya NULLS FIRST istifadə et, əgər NULL-ların yeri vacibdirsə.
- Adi aggregate əvəzinə window aggregate funksiyalarının istifadəsi
Bəzən window aggregate funksiyaları (SUM() OVER(...)) istifadə olunur, halbuki adi aggregate və GROUP BY kifayət edərdi. Bu isə sorğunu çətinləşdirir və yavaşıdır.
💡 Window funksiyalarını yalnız sətr detalını saxlamaq lazım olanda istifadə et.
GO TO FULL VERSION