İlk baxışdan, pəncərə funksiyaları və aqreqat funksiyalar məlumatların analiz və emalı üçün oxşar alətlər kimi görünür. Axı hər ikisi toplama, orta, sıralama və s. kimi hesablamalar aparır. Amma gəlin baxaq, əslində onlar nə ilə fərqlənir.
Aqreqat funksiyalar (GROUP BY)
Aqreqat funksiyalar belə işləyir:
- Sətirləri göstərilən sütunlara görə qruplaşdırır.
- Qruplaşdırmadan sonra hər bir qrup nəticədə bir sətirə çevrilir.
- Nümunə: hər region üzrə ümumi gəliri bilmək istəyirsən.
SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;
Xüsusiyyət: GROUP BY məlumatı "sıxır". Əgər qruplaşdırma istifadə edirsənsə, bir qrupa daxil olan bütün sətirlər yox olur — yalnız aqreqasiya nəticəsi qalır.
Pəncərə funksiyaları (PARTITION BY)
Pəncərə funksiyaları isə əksinə:
- Orijinal məlumat strukturunu saxlayır (heç bir sıxılma və ya sətir itməsi yoxdur!).
- "Pəncərə" daxilində — məntiqi ayrılmış sətir qruplarında — hesablamalar edə bilir.
Nümunə: hər şəhərin satışlarının öz regionundakı ümumi satışlara nisbətini bilmək istəyirsən, amma bütün məlumatları saxlamaq istəyirsən.
SELECT
region,
city,
sales,
SUM(sales) OVER (PARTITION BY region) AS total_sales_by_region
FROM sales_data;
Xüsusiyyət: pəncərə funksiyalarından istifadə sətirləri silmir, sadəcə hər sətirə yeni hesablanmış dəyərlər əlavə edir.
Nümunə: SUM() ilə GROUP BY vs SUM() ilə PARTITION BY
Fərqi daha yaxşı başa düşmək üçün baxaq, SUM() hər iki halda necə işləyir. Təsəvvür et ki, belə bir sales_data cədvəlimiz var:
| region | city | sales |
|---|---|---|
| North | CityA | 100 |
| North | CityB | 150 |
| South | CityC | 200 |
| South | CityD | 250 |
GROUP BY ilə toplama
Hər region üzrə ümumi satış həcmini bilmək istəyirik:
SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;
Nəticə belə olacaq:
| region | total_sales |
|---|---|
| North | 250 |
| South | 450 |
Nə baş verdi: sətirlər region üzrə qruplaşdı və hər qrup satışların cəmi ilə bir sətirə "sıxıldı".
PARTITION BY ilə toplama
İndi eyni şeyi pəncərə funksiyası ilə edək:
SELECT
region,
city,
sales,
SUM(sales) OVER (PARTITION BY region) AS total_sales_by_region
FROM sales_data;
Nəticə:
| region | city | sales | total_sales_by_region |
|---|---|---|---|
| North | CityA | 100 | 250 |
| North | CityB | 150 | 250 |
| South | CityC | 200 | 450 |
| South | CityD | 250 | 450 |
Nə baş verdi: PARTITION BY sətirləri "sıxmadı". Əvəzində, müəyyən pəncərələr daxilində (hər region — ayrıca pəncərədir) cəmi hesabladı.
GROUP BY nə vaxt, PARTITION BY nə vaxt istifadə olunur?
GROUP BY: son hesabatlar üçün uyğundur
GROUP BY faydalıdır, əgər məlumatı azaltmaq və qruplar səviyyəsində yekun nəticə almaq istəyirsənsə. Məsələn:
- Aylar üzrə ümumi satışlar.
- Məhsul kateqoriyaları üzrə sifarişlərin sayı.
Nümunə:
SELECT category, COUNT(*) AS total_orders
FROM orders
GROUP BY category;
PARTITION BY: analiz və detallı baxış üçün ideal
PARTITION BY uyğundur, əgər bütün sətirləri saxlamaq və hər biri üçün əlavə nəsə hesablamaq lazımdırsa. Məsələn:
- Hər məhsulun kateqoriyadakı satış payını tapmaq.
- Hər qrup daxilində sətirlərin nömrələnməsi.
Satış payının hesablanması nümunəsi:
SELECT
category,
product,
sales,
ROUND(
(sales * 100.0) / SUM(sales) OVER (PARTITION BY category),
2
) AS sales_percentage
FROM sales_data;
Nümunə: bir neçə pəncərə funksiyasının istifadəsi
Pəncərə funksiyalarının üstünlüklərindən biri birdən çox hesablamanı eyni anda istifadə etməkdir. Məsələn:
SELECT
region,
city,
sales,
SUM(sales) OVER (PARTITION BY region) AS total_sales,
RANK() OVER (PARTITION BY region ORDER BY sales DESC) AS sales_rank
FROM sales_data;
Nəticə:
| region | city | sales | total_sales | sales_rank |
|---|---|---|---|---|
| North | CityB | 150 | 250 | 1 |
| North | CityA | 100 | 250 | 2 |
| South | CityD | 250 | 450 | 1 |
| South | CityC | 200 | 450 | 2 |
Pəncərə funksiyalarının GROUP BY üzərində üstünlükləri
Orijinal məlumatların saxlanması: GROUP BY sətirləri "sıxır", amma pəncərə funksiyaları cədvəlin orijinal strukturunu saxlayır.
Bir sorğuda bir neçə hesablamalar: Fərqli PARTITION BY və ORDER BY parametrləri ilə bir neçə pəncərə funksiyasını istifadə edə bilərsən, məlumatlar qalır.
Analizdə çeviklik: Pəncərə funksiyaları hesablamaları öz ehtiyacına uyğun tənzimləməyə imkan verir: yığılan cəmlər, sıralama, pay hesablamaları və s.
Çeviklik nümunəsi
Gəlin bir neçə funksiyanı birləşdirək:
SELECT
region,
city,
sales,
SUM(sales) OVER (PARTITION BY region) AS total_sales,
AVG(sales) OVER (PARTITION BY region) AS avg_sales,
RANK() OVER (PARTITION BY region ORDER BY sales DESC) AS rank
FROM sales_data;
Nəticə:
| region | city | sales | total_sales | avg_sales | rank |
|---|---|---|---|---|---|
| North | CityB | 150 | 250 | 125.0 | 1 |
| North | CityA | 100 | 250 | 125.0 | 2 |
| South | CityD | 250 | 450 | 225.0 | 1 |
| South | CityC | 200 | 450 | 225.0 | 2 |
Məhdudiyyətlər və tipik səhvlər
Yayılmış səhvlərdən biri PARTITION BY istifadə etmək cəhdidir, halbuki məlumatı "sıxmaq" lazımdır. Məsələn, bunun əvəzinə:
SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;
Bəziləri belə yazmağa çalışır:
SELECT
region,
SUM(sales) OVER (PARTITION BY region) AS total_sales
FROM sales_data;
Amma bu bütün sətirləri qaytaracaq, məlumatı azaltmayacaq (hər zaman lazım olan deyil).
İndi artıq dəqiq bilirsən, nə vaxt GROUP BY, nə vaxt pəncərə funksiyaları istifadə etmək lazımdır. Bu, sanki çəkic və tornavida seçmək kimidir: hər ikisi mismar üçün işləyir... amma fərqli cür.
GO TO FULL VERSION