Bu dərsdə biz bir az daha yaxından tanış olacağıq o sirli NULL ilə. Əlbəttə, sənin öz səhvlərin hələ qabaqdadır, amma... xəbərdar olmaq = silahlanmaq. Gəlin NULL ilə bağlı bir neçə tipik səhvi müzakirə edək.
Səhv 1: NULL yoxlamaq üçün adi = operatorundan istifadə
SQL-də yeni başlayanların ən məşhur səhvlərindən biri — NULL dəyərinin olub-olmadığını yoxlamaq üçün = operatorundan istifadə etmək cəhdidir.
Nə baş verir?
SELECT *
FROM students
WHERE age = NULL;
Elə biləcəksən ki, bu sorğu yaş göstərilməyən bütün tələbələri göstərəcək, amma məyus olacaqsan: bu sorğu heç nə qaytarmayacaq. Niyə? Çünki NULL əslində dəyər deyil və adi müqayisə operatorları onunla işləmir. SQL-in sehrli kitabında deyildiyi kimi: "NULL birbaşa heç nə ilə müqayisə oluna bilməz".
Necə olmalıdır?
Dəyərin NULL olub-olmadığını yoxlamaq üçün IS NULL istifadə et:
SELECT *
FROM students
WHERE age IS NULL;
İndi yaş göstərilməyən bütün tələbələri alacaqsan.
Səhv 2: Aggregat funksiyalar NULL-u nəzərə almır (yalnız COUNT(*) istisna olmaqla)
Aggregat funksiyalarla sorğu işlədərkən NULL avtomatik olaraq hesablamalardan çıxarılır. Bu isə bəzən gözlənilməz nəticələrə gətirib çıxarır.
Nə baş verir?
SELECT AVG(salary) AS avg_salary
FROM employees;
Əgər salary sütununda NULL varsa, bu sətrlər sadəcə nəzərə alınmır və orta maaş həmin sətrlərsiz hesablanır. Bu isə orta maaş barədə yanlış təsəvvür yarada bilər.
Necə qarşısını almaq olar?
Aggregasiya etməzdən əvvəl NULL-u düzgün default dəyərlə əvəz etdiyinə əmin ol. Məsələn, COALESCE() istifadə et:
SELECT AVG(COALESCE(salary, 0)) AS avg_salary
FROM employees;
İndi NULL dəyərlər hesablamadan əvvəl 0 ilə əvəz olunacaq.
Səhv 3: NULL-ları bir-biri ilə müqayisə etmək
Verilənlər bazasında NULL heç nəyə bərabər deyil, hətta başqa bir NULL-a da. Bu bir az qəribə səslənə bilər.
Nə baş verir?
SELECT *
FROM students
WHERE NULL = NULL;
Bu sorğu da boş nəticə qaytaracaq. Niyə? Çünki SQL hesab edir ki, bir dəyərin olmaması başqa bir dəyərin olmaması ilə "bərabər" ola bilməz. Hə, SQL bir az filosofdur.
Necə olmalıdır?
Əgər iki NULL-un "bərabərliyini" yoxlamaq lazımdırsa, xüsusi konstruksiyalardan istifadə et, məsələn IS NULL. Məsələn:
SELECT *
FROM students
WHERE first_name IS NULL AND last_name IS NULL;
Səhv 4: NULL-a bölmək
NULL-a bölmək — təkcə səhv deyil, həm də bir növ riyazi cinayətdir, SQL isə buna mənasız nəticə — NULL ilə "cavab verir".
Nə baş verir?
SELECT 10 / NULL AS result;
Nəticə? NULL. SQL heç cəhd belə etmir ki, nə istədiyini başa düşsün.
Necə qarşısını almaq olar?
Belə anlaşılmazlıqlardan qorunmaq üçün COALESCE() və ya NULLIF() istifadə et:
SELECT 10 / COALESCE(divisor, 1) AS result
FROM calculations;
Bu sorğuda əgər divisor NULL olsa, NULL-a bölmək əvəzinə 1-ə bölünəcək.
Səhv 5: NULL ilə işləyən məntiqi operatorlar işləmir
NULL məntiqi ifadələrdə göründüyü anda hər şeyi pozur. Məsələn, TRUE AND NULL nəticəsi NULL olacaq, nə TRUE, nə də FALSE.
Nə baş verir?
SELECT *
FROM students
WHERE age > 18 OR age = NULL;
Bu halda, hətta age > 18 bəzi sətrlər üçün doğru olsa da, age sütununda NULL olan sətrlər nəticədən çıxarıla bilər. Niyə? Çünki age = NULL hissəsi NULL qaytaracaq, TRUE yox.
Necə olmalıdır?
Həmişə məntiqi şərtlərdə NULL dəyərləri açıq şəkildə yoxla:
SELECT *
FROM students
WHERE age > 18 OR age IS NULL;
Səhv 6: NULL ilə sıralamada qeyri-müəyyən davranış (ən "ağır" səhv)
Əgər sorğuda ORDER BY istifadə edirsənsə, NULL sətrlərin necə sıralanacağı səni təəccübləndirə bilər. Default olaraq PostgreSQL NULL olan sətrləri artan sıralamada sona, azalan sıralamada isə əvvələ qoyur.
Nə baş verir?
SELECT product_name, price
FROM products
ORDER BY price;
Əgər price NULL olarsa, bu sətrlər siyahının sonunda görünəcək.
Gözlənilməzlikdən necə qaçmaq olar?
NULL üçün sıralamanı açıq şəkildə göstərə bilərsən: NULLS FIRST və ya NULLS LAST:
SELECT product_name, price
FROM products
ORDER BY price NULLS FIRST;
Səhv 7: Xarici açarlarla və NULL ilə düzgün işləməmək
Xarici açar olan sütunlarda NULL dəyərlər bəzən gözlənilməz davranışa səbəb ola bilər.
Nə baş verir?
Əgər cədvələ xarici açar əlavə etmisənsə və sətri əlavə edərkən xarici açar sahəsini boş qoyursansa, PostgreSQL heç bir reaksiya verməyəcək. Çünki NULL dəyərlər bağlı cədvəllərdə yoxlanılmır.
Necə düzgün işləmək olar?
Əgər belə sahələrdə NULL istifadəsini istəmirsənsə, NOT NULL məhdudiyyəti qoy. Yaxud sadəcə unutma ki, NULL dəyərlər "yetim" kimi qalır, heç bir bağlı cədvələ aid olmur.
Bağlı cədvəllər və xarici açarlar haqqında daha ətraflı növbəti dərsdə öyrənəcəksən :P
GO TO FULL VERSION