Hələ danışmadığımız bir şey var: aqreqat funksiyalardan sonra qrupları necə filtrləmək olar? Bəzən bizə bütün fakültələr lazım deyil — sadəcə tələbə sayı yüzdən çox olanlar maraqlıdır. Ya da bizə yalnız orta maaşı 50,000-dən yuxarı olan departamentlər lazımdır. Bu gün HAVING ilə aqreqasiya olunmuş dataların filtrlenməsi ilə tanış olacağıq.
Bəs bizə HAVING niyə lazımdır, axı WHERE var? Sadəcə WHERE-i GROUP BY-dan sonra qoymaq olmur? :)
Hər şey o qədər də sadə deyil! Əvvəla, SQL-də operatorların sırası sabitdir və WHERE bu sıraya görə GROUP BY-dan əvvəl işləyir.
Bəlkə onu GROUP BY-dan sonra yerləşdirmək olar?
O da olmur! Çox vaxt cədvəldəki sətirləri qruplaşdırmadan əvvəl filtrləmək lazımdır. Sonra filtrdən keçən datanı qruplaşdırırsan. Və sonra qruplaşdırmadan sonra lazımsız dataları atırsan.
Bəs onda sadəcə WHERE operatorunu götürüb, adını HAVING qoyub GROUP BY-dan sonra yerləşdirək?
Hə, məhz belə edirik! :)
HAVING və WHERE fərqi
WHERE qruplaşdırmadan əvvəl sətirləri filtrləyir.
Təsəvvür elə, tortları dadına görə seçirsən: çiyələkli və şokoladlıları saxlayırsan, qalanları kənara qoyursan. Bu WHERE-in işidir.
HAVING isə datalar qruplaşdırılıb, aqreqat funksiyalar işini gördükdən sonra filtrləyir.
Məsələn, artıq tortları masalara görə qruplaşdırmısan, sayını hesablamısan və indi yalnız 3-dən çox tort olan masaları saxlamaq istəyirsən.
Yəni HAVING qrup səviyyəsində dataları filtrləmək üçün istifadə olunur.
HAVING sintaksisi
Sintaksis demək olar ki, WHERE kimidir, amma bir az fərqli işləyir:
SELECT sütunlar, aqreqat_funksiyalar
FROM cədvəl
GROUP BY sütunlar
HAVING şərt;
İcra mərhələləri:
- Əvvəlcə sətirlər
WHEREilə filtrlənir. - Sonra datalar
GROUP BYilə qruplaşdırılır. - Qruplaşdırmanın nəticəsinə aqreqat funksiyalar tətbiq olunur.
- Sonda alınan nəticə
HAVINGilə filtrlənir.
HAVING istifadəsinə nümunələr
Nümunə 1: Tələbə sayı çox olan fakültələrin filtrlənməsi
Universitetdə hansı fakültələrdə 100-dən çox tələbə olduğunu bilmək istəyirsən. Tutaq ki, students cədvəlimiz var:
| id | name | faculty |
|---|---|---|
| 1 | Alice | Engineering |
| 2 | Bob | Engineering |
| 3 | Charlie | Arts |
| 4 | Daisy | Business |
| 5 | ... | ... |
Sorgu:
SELECT faculty, COUNT(*) AS student_count
FROM students
GROUP BY faculty
HAVING COUNT(*) > 100;
Burda nə baş verir:
- Əvvəlcə
facultysütununa görə tələbələriGROUP BYilə qruplaşdırırıq. - Sonra
COUNT(*)aqreqat funksiyası hər fakültədə tələbə sayını hesablayır. - Sonda
HAVINGtələbə sayı 100 və ya az olan fakültələri atır.
Nəticə:
| faculty | student_count |
|---|---|
| Engineering | 150 |
| Arts | 120 |
Nümunə 2: Yüksək orta maaşı olan departamentlər
Yalnız orta əmək haqqı 50,000-dən çox olan departamentləri tapmaq istəyirsən. Tutaq ki, employees cədvəlimiz var:
| id | name | department | salary |
|---|---|---|---|
| 1 | Alice | IT | 60000 |
| 2 | Bob | HR | 45000 |
| 3 | Charlie | IT | 70000 |
| 4 | Daisy | HR | 52000 |
| 5 | ... | ... | ... |
Sorgu:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
Nəticə:
| department | avg_salary |
|---|---|
| IT | 65000 |
Diqqət et: HAVING yalnız GROUP BY-dan sonra hesablanmış nəticələrlə işləyir.
WHERE, GROUP BY və HAVING icra ardıcıllığı
WHERE və HAVING ilə filtrasiya fərqli mərhələlərdə baş verir. Fərqi daha yaxşı başa düşmək üçün gəlin sorğunu addım-addım izləyək:
WHERE: sətirlərin filtrasiyası.Bu mərhələdə cədvəldəki bütün sətirlər işlənir. Əgər sətir
WHEREşərtindən keçmirsə, ümumiyyətlə növbəti mərhələyə düşmür.GROUP BY: sətirlərin qruplaşdırılması.Filtrasiyadan sonra sətirlər
GROUP BY-da göstərilən sütunlara görə qruplaşdırılır.Aqreqat funksiyalar:
Qruplaşdırılmış datalara
COUNT(),AVG(),SUM()və s. kimi aqreqat funksiyalar tətbiq olunur.HAVING: qrupların filtrasiyası.Bu mərhələdə yalnız aqreqat nəticələr işlənir.
HAVINGşərtləri yalnız qruplara tətbiq olunur.
HAVING işləmə xüsusiyyətləri
Xüsusiyyət 1: Aqreqatlarla işləmək
HAVING ilə WHERE arasındakı əsas fərq — aqreqat funksiyalarla işləməsidir. Məsələn:
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;
Bu sorğuda AVG(salary)-i WHERE-də istifadə etmək olmur, çünki WHERE qruplaşdırmadan əvvəl işləyir. Belə bir sorğu:
SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000
GROUP BY department;
səhv verəcək: aggregate functions are not allowed in WHERE.
Xüsusiyyət 2: Qruplaşdırma olmadan filtrasiya
HAVING-i hətta açıq GROUP BY olmadan da istifadə edə bilərsən. Bu halda sorğu sanki bir qrup — bütün sətirlər — kimi işləyəcək:
SELECT AVG(salary) AS avg_salary
FROM employees
HAVING AVG(salary) > 50000;
Praktik nümunə
Tutaq ki, mağazamız və sales adlı satış cədvəlimiz var:
| id | product_id | sales_amount |
|---|---|---|
| 1 | 101 | 200.00 |
| 2 | 102 | 300.00 |
| 3 | 101 | 400.00 |
| 4 | 103 | 150.00 |
Sorgu: ümumi satış həcmi 500-dən çox olan məhsulları tapmaq.
SELECT product_id, SUM(sales_amount) AS total_sales
FROM sales
GROUP BY product_id
HAVING SUM(sales_amount) > 500;
Nəticə:
| product_id | total_sales |
|---|---|
| 101 | 600.00 |
Tipik səhvlər
Aqreqatları WHERE-də istifadə etmək:
Məsələn:
SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000
GROUP BY department;
Səhv: aqreqat funksiyaları WHERE-də istifadə etmək olmaz.
NULL ilə bağlı səhvlər:
Əgər datada NULL varsa, filtrasiya gözlənilməz nəticələr verə bilər. Məsələn:
SELECT department, SUM(salary)
FROM employees
GROUP BY department
HAVING SUM(salary) > 0;
Əgər salary sütununda yalnız NULL varsa, nəticə sıfır və ya boş ola bilər.
Təbriklər. Artıq bu mərhələdə aqreqasiya olunmuş dataları rahat filtrləyə bilirsən! Unutma, HAVING — qrup səviyyəsində analitika üçün əsas açardır, harada ki, adi WHERE bəs etmir.
GO TO FULL VERSION