Məzmuna keç
Educora
Orta16 dəq7 / 22

GROUP BY və HAVING: qruplar üzrə yekunlar

Sətirləri qruplara böl, hər qrup üçün aqreqatları hesabla və HAVING ilə qrupları süz.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • GROUP BY ilə hər qrup üçün yekun hesablamaq
  • WHERE və HAVING arasındakı fərqi izah etmək
  • Sorğu hissələrinin məntiqi icra ardıcıllığını bilmək

Direktor soruşur: «Hər şəhərdən neçə şagirdimiz var?» Keçən dərsdən bilirik ki, COUNT(*) və WHERE city = 'Bakı' ilə bir şəhəri saymaq olar. Amma yeddi şəhər üçün yeddi sorğu yazmaq? Yox — GROUP BY bütün şəhərlər üçün cavabı bir sorğu ilə verir.

GROUP BY: sətirləri qruplara bölmək

GROUP BY sütun eyni qiymətli sətirləri bir qrupa yığır, aqreqat funksiya isə hər qrup üçün ayrıca hesablanır. Nəticədə hər qrup üçün bir sətir olur.

SQL
SELECT city, COUNT(*) AS students
FROM students
GROUP BY city
ORDER BY students DESC, city;
▸ Gözlənilən nəticə
city | students
Bakı | 4
Gəncə | 2
Sumqayıt | 2
Lənkəran | 1
Naxçıvan | 1
Quba | 1
Şəki | 1
  1. FROM students cədvəlin 12 sətrini götürür.
  2. GROUP BY city şəhəri eyni olan sətirləri bir «səbətə» qoyur — 7 səbət alınır.
  3. COUNT(*) hər səbətdəki sətirləri sayır.
  4. Hər səbətdən bir sətir qalır: şəhər və say.

Bir qrup üçün bir neçə aqreqat da hesablamaq olar. Aşağıda hər kateqoriya üçün məhsulların sayı, orta qiyməti və anbardakı ümumi miqdarı var.

SQL
SELECT category,
       COUNT(*)             AS products,
       ROUND(AVG(price), 2) AS avg_price,
       SUM(stock)           AS total_stock
FROM products
GROUP BY category
ORDER BY category;
▸ Gözlənilən nəticə
category | products | avg_price | total_stock
Accessories | 2 | 33.5 | 180
Electronics | 4 | 695.12 | 63
Games | 1 | 42 | 18
Home | 1 | 34.99 | 25
Stationery | 2 | 5.55 | 800

Bir neçə sütun və ifadə üzrə qruplaşdırma

GROUP BY-da bir neçə sütun yazanda qrupu qiymətlərin birləşməsi müəyyən edir. Məsələn, ölkə və şəhər cütü üzrə müştəriləri sayaq.

SQL
SELECT country, city, COUNT(*) AS customers
FROM customers
GROUP BY country, city
ORDER BY country, city;
▸ Gözlənilən nəticə
country | city | customers
Azerbaijan | Bakı | 2
Azerbaijan | Gəncə | 1
Russia | Moscow | 1
Türkiye | Ankara | 1
Türkiye | İstanbul | 1
United Kingdom | London | 1

İfadəyə görə də qruplaşdırmaq olar. SUBSTR(order_date, 1, 7) tarixdən ilk 7 simvolu, yəni ili və ayı (2025-04) kəsir — beləcə sifarişləri aylar üzrə sayırıq. SQL Server-də bu funksiya SUBSTRING adlanır.

SQL
SELECT SUBSTR(order_date, 1, 7) AS month,
       COUNT(*) AS orders
FROM orders
GROUP BY SUBSTR(order_date, 1, 7)
ORDER BY month;
▸ Gözlənilən nəticə
month | orders
2025-01 | 2
2025-02 | 2
2025-03 | 2
2025-04 | 2
2025-05 | 1
2025-06 | 2
2025-07 | 1

HAVING: qrupları süzmək

Yalnız ən azı iki şagirdi olan şəhərlər lazımdırsa nə etməli? WHERE COUNT(*) >= 2 yazmaq olmaz: WHERE qruplar yaranmamışdan əvvəl tək-tək sətirlərə baxır və hələ heç nə sayılmayıb. Qruplar üçün şərt HAVING-də yazılır — o, qruplaşdırmadan sonra işləyir.

SQL
SELECT city, COUNT(*) AS students
FROM students
GROUP BY city
HAVING COUNT(*) >= 2
ORDER BY city;
▸ Gözlənilən nəticə
city | students
Bakı | 4
Gəncə | 2
Sumqayıt | 2
SQL
SELECT course_id, ROUND(AVG(score), 1) AS avg_score
FROM enrollments
GROUP BY course_id
HAVING AVG(score) >= 85
ORDER BY avg_score DESC;
▸ Gözlənilən nəticə
course_id | avg_score
6 | 92.7
5 | 90.5
1 | 87.3
Orta balı 85 və daha yüksək olan kurslar.
MeyarWHEREHAVING
Nəyi süzürayrı-ayrı sətirləriqrupları
Nə vaxt işləyirqruplaşdırmadan əvvəlqruplaşdırmadan sonra
Aqreqat yazmaq olar?yoxbəli

WHERE və HAVING bir sorğuda birlikdə işləyə bilər. Aşağıda əvvəlcə WHERE anbarda olmayan məhsulu (Monitor) atır, sonra qalanlar kateqoriyalara bölünür, HAVING isə yalnız birdən çox məhsulu olan kateqoriyaları saxlayır.

SQL
SELECT category, COUNT(*) AS in_stock
FROM products
WHERE stock > 0
GROUP BY category
HAVING COUNT(*) > 1
ORDER BY category;
▸ Gözlənilən nəticə
category | in_stock
Accessories | 2
Electronics | 3
Stationery | 2

Sorğunun icra ardıcıllığı

Sorğunu biz bir qaydada yazırıq, VBİS isə onu məntiqi olaraq başqa qaydada icra edir. Bu ardıcıllığı bilmək bir çox səhvi izah edir: məsələn, WHERE-də aqreqat və ləqəb niyə işləmir, ORDER BY-da isə niyə işləyir.

  1. FROM — cədvəldən sətirlər götürülür
  2. WHERE — sətirlər süzülür
  3. GROUP BY — sətirlər qruplara bölünür
  4. HAVING — qruplar süzülür
  5. SELECT — sütunlar və ləqəblər hesablanır
  6. ORDER BY — nəticə sıralanır
  7. LIMIT — lazım olan sayda sətir götürülür
Nümunə tapşırıq

Hansı müştərilər bütün sifarişlərində birlikdə ən azı 5 ədəd mal alıb?

Həllini göstər
1) Sifarişləri müştəriyə görə qruplaşdırırıq: GROUP BY customer_id.
2) Hər qrup üçün miqdarları toplayırıq: SUM(quantity).
3) Qrupları süzürük: HAVING SUM(quantity) >= 5.
Cavab: 2 nömrəli müştəri (21 ədəd) və 1 nömrəli müştəri (13 ədəd).
SQL
SELECT customer_id, SUM(quantity) AS items
FROM orders
GROUP BY customer_id
HAVING SUM(quantity) >= 5
ORDER BY items DESC;
▸ Gözlənilən nəticə
customer_id | items
2 | 21
1 | 13
Müştərilərin adlarını da görmək üçün orders cədvəlini customers ilə birləşdirmək lazımdır — bunu növbəti dərsdə öyrənəcəksən.
Tapşırıq

courses cədvəlində hər fənn (subject) üçün kursların sayını (courses) və kreditlərin cəmini (credits) göstər. Nəticəni fənnin adına görə düz.

Tapşırıq · SQL
SELECT subject
FROM courses
ORDER BY subject;
▸ Gözlənilən nəticə
subject | courses | credits
Chemistry | 1 | 3
English | 1 | 2
History | 1 | 2
Informatics | 1 | 3
Math | 2 | 7
Physics | 1 | 4
Tapşırıq

Orta balı 85-dən yüksək olan şagirdləri tap: student_id və 1 onluq rəqəmə qədər yuvarlaqlaşdırılmış orta bal (avg_score). Orta bala görə azalan, bərabər olduqda student_id-yə görə artan sırada düz.

Tapşırıq · SQL
SELECT student_id, ROUND(AVG(score), 1) AS avg_score
FROM enrollments
-- group and filter the groups
▸ Gözlənilən nəticə
student_id | avg_score
11 | 95.5
3 | 92.5
10 | 91
1 | 90
5 | 89
6 | 88

Əsas fikirlər

  • GROUP BY eyni qiymətli sətirləri qruplaşdırır; nəticədə hər qrup üçün bir sətir olur.
  • SELECT-dəki hər sütun ya GROUP BY-da, ya da aqreqatın içində olmalıdır.
  • WHERE sətirləri qruplaşdırmadan əvvəl, HAVING isə qrupları sonra süzür.
  • Aqreqatlı şərtlər (COUNT(*) >= 2) yalnız HAVING-də yazılır.
  • Məntiqi ardıcıllıq: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
SELECT city, COUNT(*) FROM students GROUP BY city sorğusunda GROUP BY city nə edir?