İndi isə gəlin bu funksiyalardan istifadə edərkən yaranan tipik səhvlərə daha dərindən baxaq. Hətta ən təcrübəli SQL ustaları belə bəzən bu tələlərə düşür, bizim məqsədimiz isə onları vaxtında görmək və rahatca yan keçməkdir.
Heç olub ki, bir sorğu yazırsan və o, sənə qəribə bir şey barədə şikayət edir, məsələn "column must appear in the GROUP BY clause or be used in an aggregate function"? Yaxud nəticə qəribə görünür, amma niyə belə olduğunu başa düşmürsən? Bu, aqrəqat funksiyaları ilə işləyərkən rast gəlinən tipik səhvlərin yalnız görünən hissəsidir. Bu leksiya — səhvlər və anlaşılmazlıqlar dənizində sağ qalmaq üçün sənin bələdçindir.
Səhv 1: GROUP BY xaricində qeyri-aqrəqat sütunun istifadəsi
Problem
Sən bir sorğu yazmısan ki, aqrəqatlaşdırılmış məlumat qaytarsın, amma arada bir sütun əlavə etmisən ki, nə qruplaşmada var, nə də aqrəqat funksiyasına bükülüb. Məsələn:
SELECT department, salary, SUM(salary)
FROM employees
GROUP BY department;
PostgreSQL dərhal sənə deyəcək:
ERROR: column "employees.salary" must appear in the GROUP BY clause or be used in an aggregate function
Niyə belə olur?
GROUP BY istifadə edəndə, PostgreSQL sətirləri göstərilən sütunlara görə birləşdirir. Amma əlavə bir sütun (bu halda salary) əlavə etsən, PostgreSQL bilmir ki, sən ondan bir dənə maaş istəyirsən, orta dəyər, yoxsa başqa bir şey.
Necə düzəltmək olar? İki yol var:
- Bütün qeyri-aqrəqat sütunların
GROUP BY-da olduğuna əmin ol:
SELECT department, salary
FROM employees
GROUP BY department, salary;
- Yaxud, əgər məntiqlidirsə, sütunu aqrəqat funksiyasına bük:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
Məsləhət: əgər PostgreSQL GROUP BY-a görə şikayət edirsə, özündən soruş: "Bu sütun həqiqətən lazımdırmı? Lazımdırsa, o, hansı rolu oynayır?"
Səhv 2: COUNT() və NULL ilə səhv işləmək
Problem: sən istəyirsən biləsən neçə işçi bonusunu göstərib və belə yazırsan:
SELECT COUNT(bonus) AS bonus_count
FROM employees;
Amma birdən görürsən ki, nəticə gözlədiyindən azdır. Niyə? Çünki COUNT(column) o sətirləri saymır ki, column NULL-dır.
Həll: əgər bütün sətirləri saymaq istəyirsənsə, COUNT(*) istifadə et:
SELECT COUNT(*) AS total_count
FROM employees;
Yaxud dəqiqləşdir ki, sənə yalnız bonusu NULL olmayan sətirlər lazımdır:
SELECT COUNT(bonus) AS bonus_count
FROM employees
WHERE bonus IS NOT NULL;
İpucu: əgər NULL olan qeydlərlə, yəni cədvəldə ümumiyyətlə qeyd olmayanlarla fərqi nəzərə almaq istəyirsənsə, COUNT(*) və COUNT(column) arasında diqqətlə seçim et.
Səhv 3: HAVING əvəzinə WHERE ilə filtrasiya etməyi unutmaq
Problem: sən istəyirsən o şöbələri tapasan ki, orta maaş 5000-dən çoxdur. Yeni başlayan proqramçı belə bir şey yaza bilər:
SELECT department, AVG(salary) AS avg_salary
FROM employees
WHERE AVG(salary) > 5000
GROUP BY department;
PostgreSQL sənə səhv atacaq:
ERROR: aggregate functions are not allowed in WHERE clause
Bu ona görədir ki, WHERE səviyyəsində filtrasiya qruplaşmadan əvvəl baş verir, aqrəqat funksiyalar isə qruplaşmadan sonra tətbiq olunur. Yəni, AVG(salary) hələ WHERE mərhələsində hesablanmayıb.
Bunu düzəltmək üçün, aqrəqatlaşdırılmış məlumatı filtrləmək üçün HAVING istifadə et:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 5000;
Səhv 4: WHERE ilə filtrasiya və icra ardıcıllığında çaşqınlıq
Problem: sən bilmək istəyirsən ki, hansı şöbələrdə işçilərin yaşı 30-dan çoxdur və neçə nəfərdir. Sorğu belə ola bilər:
SELECT department, COUNT(*)
FROM employees
GROUP BY department
WHERE age > 30;
PostgreSQL yenə səni məyus edəcək:
ERROR: syntax error at or near "WHERE"
Niyə belə olur? WHERE operatoru həmişə GROUP BY-dan əvvəl işlənir. Bu halda sən sadəcə WHERE-ı səhv yerə qoymusan.
Belə vəziyyətdən qaçmaq üçün, əvvəlcə sətirləri filtrlə, sonra qruplaşdırmanı et.
SELECT department, COUNT(*)
FROM employees
WHERE age > 30
GROUP BY department;
Səhv 5: NULL ilə SUM(), AVG() və digər funksiyalardan istifadə
Problem: sən istəyirsən işçilərə verilmiş ümumi bonusu tapasan və belə yazırsan:
SELECT SUM(bonus) AS total_bonus
FROM employees;
Amma nəticə qəribə dərəcədə az görünür. Çünki işçilərin yarısında bonus göstərilməyib və bu NULL-lar sadəcə sayılmır.
Həll: NULL-ları əvvəlcədən emal et. Məsələn, NULL-u 0 ilə əvəz edə bilərsən:
SELECT SUM(COALESCE(bonus, 0)) AS total_bonus
FROM employees;
İndi bütün NULL-lar 0-a çevriləcək və cəmin nəticəsi düzgün olacaq.
COALESCE funksiyasının necə işlədiyini bir neçə leksiyadan sonra daha ətraflı baxacağıq.
Səhv 6: Bir neçə aqrəqat funksiyanı əlaqəsini başa düşmədən istifadə etmək
Problem: sən istəyirsən ümumi işçi sayını və ümumi maaşı hesablamaq. Amma elə bir şey yazırsan ki, qəribə nəticələr qaytarır:
SELECT COUNT(salary) AS count_salary, SUM(salary) AS total_salary
FROM employees;
Niyə burada hər şey səhv gedə bilər? Əgər kimsə maaşını NULL qoyubsa, COUNT(salary) və SUM(salary) fərqli nəticələr verəcək və bu, çaşdırıcı ola bilər.
Həmişə yadında saxla ki, aqrəqat funksiyalar bir-birindən asılı olmadan işləyir. Əgər NULL varsa, nəticələr fərqli olacaq. COALESCE və ya COUNT(*) istifadə et ki, nəticələr eyni olsun:
SELECT COUNT(*) AS total_employees, SUM(COALESCE(salary, 0)) AS total_salary
FROM employees;
Səhv 7: Böyük qruplaşmalarla optimallaşdırılmamış sorğular
Problem: sən çoxlu qruplaşma ilə sorğu işə salırsan və o, beş dəqiqə əvəzinə beş saat işləyir:
SELECT department, job_title, location, COUNT(*)
FROM employees
GROUP BY department, job_title, location;
Qruplaşdırmanı etməzdən əvvəl düşün, həqiqətən bütün bu sütunlar GROUP BY-da lazımdırmı? Qrupda nə qədər çox unikal dəyər varsa, sorğu bir o qədər uzun çəkəcək. Əgər mümkündürsə, qruplaşmanı azaldın:
SELECT department, COUNT(*)
FROM employees
GROUP BY department;
Bu səhvlər çox yayılıb və hətta ən təcrübəli SQL proqramçıları da onlarla rastlaşır. Ümid edirəm, indi bu tələləri daha rahat keçəcəksən və sorğuların həm sürətli, həm düzgün, həm də gözəl olacaq.
GO TO FULL VERSION