CodeGym /Kurslar /SQL SELF /OVER() sintaksisi və əsas xüsusiyyətləri

OVER() sintaksisi və əsas xüsusiyyətləri

SQL SELF
Səviyyə , Dərs
Mövcuddur

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ür
  • ORDER BY — hər qrupun içində sətrlərin sırasını təyin edir
  • ROWS/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?

  1. ROW_NUMBER() hər sətrə unikal nömrə verir.
  2. OVER() içində heç bir parametr olmadığı üçün, employees cə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?

  1. employees cədvəlindən datalar department_id dəyərinə görə qruplaşdırılır.
  2. 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?

  1. Data qruplara bölünür (PARTITION BY department_id).
  2. Hər qrupda sətrlər maaşa görə azalan sırada düzülür (ORDER BY salary DESC).
  3. 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?

  1. ROW_NUMBER() hər qrupda sətrləri maaşa görə azalan sırada nömrələyir.
  2. 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

  1. PARTITION BY olmaması

Ə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ə.


  1. ORDER BY iç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.

  1. ROWS BETWEEN yanlış 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.

  1. NULL ilə 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()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ə.

  1. 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.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION