Gəlin bir daha SQL-də əməliyyatların icra ardıcıllığına baxaq, həmçinin WHERE və HAVING-in nələrlə işləyə biləcəyini və nələrlə işləyə bilmədiyini müzakirə edək. Bu vacib məqamdır, çünki SQL-sorğularının bir çox incəlikləri bunun üzərində qurulur. Bunu yaxşı başa düşməlisən.
Bəs WHERE ilə HAVING arasında fərq nədir, hansını nə vaxt istifadə etmək lazımdır və bunlar bir-biri ilə necə əlaqəlidir? Bu, sorğuların məntiqində çaşqınlıq yaşamamağa və məlumatları effektiv filtrləməyə kömək edəcək. Gəlin WHERE və HAVING haqqında bildiklərimizi ümumiləşdirək.
WHERE nədir?
WHERE — bu, qruplaşdırmadan və ya aqreqat funksiyalardan əvvəl sətirləri filtrləmək üçün istifadə olunan şərtdir. Yəni, əvvəlcə cədvəldən kriteriyalara uyğun sətirlər seçilir, sonra isə qalan məlumatlar üzərində qruplaşdırma aparılır.
👉 Təsəvvür elə ki, bazarda meyvə yığırsan. WHERE — bu, sənə əvvəlcədən keyfiyyətsiz almaları ayırmağa kömək edən filtrlədir, hələ onları ölçüsünə və ya rənginə görə ayırmamısan.
Nümunə:
SELECT *
FROM students
WHERE age > 18;
Bu sorğu 18 yaşdan böyük olan bütün tələbələri qruplaşdırmadan əvvəl seçəcək.
HAVING nədir?
HAVING — bu, məlumatlar qruplaşdırıldıqdan sonra (GROUP BY) tətbiq olunan filtrlədir. O, qruplaşdırılmış məlumatlara şərt qoymağa imkan verir, məsələn, yalnız tələbələrin orta balı 80-dən yuxarı olan qrupları saxlamaq.
👉 Yenə alma nümunəsinə qayıdaq. HAVING — bu, artıq almaları səbətlərə (qrup) ayırdıqdan sonra istifadə olunan filtrlədir. İndi səni, məsələn, yalnız 10-dan çox alma olan səbətlər (qruplar) maraqlandırır.
Nümunə:
SELECT səbət, COUNT(*)
FROM almalar
GROUP BY səbət
HAVING COUNT(*) > 10;
Bu sorğu yalnız almaların sayı 10-dan çox olan səbətləri seçəcək.
Əsas fərqlər:
| Xüsusiyyət | WHERE |
HAVING |
|---|---|---|
| Tətbiq | Qruplaşdırmadan əvvəl sətirləri filtrləyir | Qruplaşdırmadan sonra qrupları filtrləyir |
| Aqreqasiya ilə işləmə | Aqreqat funksiyalardan istifadə etmək olmaz | Aqreqat funksiyalardan istifadə etmək olar |
| Məqsəd | Qruplaşdırma üçün artıq sətirləri silir | Şərtə uyğun olmayan qrupları silir |
WHERE, GROUP BY və HAVING-in icra ardıcıllığı
WHERE və HAVING-in necə işlədiyini daha yaxşı başa düşmək üçün gəlin SQL-sorğularının icra ardıcıllığına baxaq:
- Əvvəlcə
FROMicra olunur, cədvəldən sətirlər seçilir. - Sonra
WHEREtətbiq olunur, yalnız şərtə uyğun sətirlər filtrlənir. - Bundan sonra
GROUP BYilə qruplaşdırma aparılır. Yeni qrup məlumatları cədvəli alınır. HAVINGtətbiq olunur, şərtə uyğun qruplar filtrlənir.- Sonda
SELECTnəticələri seçilir.
Bunu sxematik belə göstərmək olar:
1. FROM → 2. WHERE → 3. GROUP BY → 4. HAVING → 5. SELECT
Nümunə:
SELECT department, AVG(age) AS avg_age
FROM students
WHERE age > 18
GROUP BY department
HAVING AVG(age) > 20;
Burada belə olur:
studentscədvəlindəage > 18olan sətirlər seçilir (WHEREistifadə olunur).- Qalan sətirlər
departmentüzrə qruplaşdırılır. - Hər qrup üçün tələbələrin orta yaşı hesablanır.
- Orta yaş 20-dən az və ya bərabər olan qruplar
HAVINGilə çıxarılır. - Nəticələr göstərilir.
Kombinə edilmiş istifadə nümunələri
Nümunə 1: Qruplaşdırmadan əvvəl və sonra filtrləmə
Şərt: 5-dən çox tələbəsi olan fakültələri tapmaq, amma yalnız 18 yaşdan böyük tələbələr nəzərə alınır.
İlkin cədvəl students
| id | name | department | age | gpa |
|---|---|---|---|---|
| 1 | Alex Lin | ComputerSci | 20 | 3.8 |
| 2 | Maria Chi | Math | 22 | 3.5 |
| 3 | Anna Song | ComputerSci | 19 | 4.0 |
| 4 | Otto Art | Math | 17 | 3.9 |
| 5 | Liam Park | Physics | 21 | 3.7 |
| 6 | Jane Doe | ComputerSci | 23 | 3.6 |
| 7 | Tom Brown | Math | 25 | 3.4 |
| 8 | Sara White | Math | 19 | 3.8 |
| 9 | John Smith | ComputerSci | 20 | 3.7 |
| 10 | Emily Green | Physics | 18 | 3.9 |
| 11 | Mark Blue | ComputerSci | 21 | 3.5 |
| 12 | Zoe Black | Math | 22 | 3.6 |
| 13 | Max Gray | ComputerSci | 20 | 3.9 |
| 14 | Eva Gold | Math | 23 | 3.7 |
| 15 | Nick Silver | Physics | 19 | 3.8 |
Sorğu:
SELECT department, COUNT(*) AS student_count
FROM students
WHERE age > 18
GROUP BY department
HAVING COUNT(*) > 5;
Nəticə: -- Sorğunun nəticəsi
| department | student_count |
|---|---|
| ComputerSci | 6 |
İzah:
- Əvvəlcə
age <= 18olan sətirləri silirik (WHEREşərti). - Məlumatları fakültələrə görə qruplaşdırırıq (
GROUP BY department). - Hər qrupda tələbələrin sayını hesablayırıq.
- Tələbə sayı 5-dən az və ya bərabər olan qrupları çıxarırıq (
HAVING COUNT(*) > 5).
Nümunə 2: WHERE əvəzinə HAVING istifadə edərkən səhv
Şərt: Orta yaşı 22-dən böyük olan fakültələri tapmaq.
Səhv sorğu:
SELECT department, AVG(age) AS avg_age
FROM students
WHERE AVG(age) > 22
GROUP BY department;
Səhv: SQL-də AVG kimi aqreqat funksiyalardan WHERE-də istifadə etmək olmaz, çünki bu mərhələdə aqreqatlar hələ hesablanmayıb.
Düzgün sorğu:
SELECT department, AVG(age) AS avg_age
FROM students
GROUP BY department
HAVING AVG(age) > 22;
Burada AVG(age) > 22 şərti qruplaşdırmadan sonra tətbiq olunur.
Praktik məsləhətlər
Əgər sətirləri filtrləmək lazımdırsa, WHERE istifadə et. Nümunə: Maaşı 5000-dən çox olan bütün işçiləri tapmaq.
SELECT *
FROM employees
WHERE salary > 5000;
Əgər qrupları filtrləmək lazımdırsa, HAVING istifadə et. Nümunə: Ümumi maaşı 100 000-dən çox olan şöbələri tapmaq.
SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department
HAVING SUM(salary) > 100000;
Çətin şərtlər üçün WHERE və HAVING-i birləşdir.
Nümunə: Yalnız əhalisi 1 milyon nəfərdən çox olan şəhərləri nəzərə alaraq, ümumi əhalisi 10 milyon nəfərdən çox olan ölkələri tapmaq.
SELECT country, SUM(population) AS total_population
FROM cities
WHERE population > 1000000
GROUP BY country
HAVING SUM(population) > 10000000;
Tipik səhvlər və onların həlli yolları
Ən çox rast gəlinən səhvlərdən biri WHERE və HAVING arasında çaşqınlıqdır. Məsələn, WHERE-də aqreqat funksiyadan istifadə cəhdi:
SELECT department, COUNT(*)
FROM students
WHERE COUNT(*) > 10
GROUP BY department;
Belə sorğu səhv verəcək, çünki WHERE mərhələsində aqreqat hesablamalar mövcud deyil. Düzgün yanaşma — HAVING istifadə etməkdir:
SELECT department, COUNT(*)
FROM students
GROUP BY department
HAVING COUNT(*) > 10;
Başqa bir səhv isə WHERE üçün düzgün olmayan şərtlərin seçilməsidir. Məsələn:
SELECT department, AVG(age) AS avg_age
FROM students
WHERE avg_age > 20
GROUP BY department;
Burada avg_age > 20 şərti səhvdir, çünki avg_age hələ hesablanmayıb. Həll — bu şərti HAVING-ə keçirməkdir:
SELECT department, AVG(age) AS avg_age
FROM students
GROUP BY department
HAVING AVG(age) > 20;
Ümid edirəm, artıq WHERE və HAVING arasındakı fərqi, onları necə düzgün istifadə etməyi və tipik səhvlərdən necə qaçmağı yaxşı başa düşürsən. Bu biliklər sənə mürəkkəb hesabatlar yaratmaqda, analiz üçün məlumatları filtrləməkdə və sorğuları optimallaşdırmaqda kömək edəcək. Yəni, yazacağın real SQL-sorğularının yarısından çoxunda bu lazım olacaq :)
GO TO FULL VERSION