11-bo‘lim
NULL semantikasi
NULL nima anglatadi, uch qiymatli mantiq, NULL bilan taqqoslash, agregatsiya va UNIQUE dagi xatti-harakati.
Ushbu bo‘lim mundarijasi
NULL - "nol" ham, "bo'sh satr" ham emas. U "noma'lum" degani
va shu sababli boshqa qoidalar bo'yicha ishlaydi.
NULL nima emas #
CREATE TABLE sinov (
id INT PRIMARY KEY AUTO_INCREMENT,
izoh VARCHAR(50),
son INT
);
INSERT INTO sinov (izoh, son) VALUES
('matn', 10),
('', 0),
(NULL, NULL);
SELECT id,
izoh,
izoh IS NULL AS null_mi,
izoh = '' AS bosh_satrmi,
son,
son IS NULL AS son_null_mi,
son = 0 AS son_nolmi
FROM sinov
ORDER BY id;
+----+------+---------+-------------+------+-------------+-----------+
| id | izoh | null_mi | bosh_satrmi | son | son_null_mi | son_nolmi |
+----+------+---------+-------------+------+-------------+-----------+
| 1 | matn | 0 | 0 | 10 | 0 | 0 |
| 2 | | 0 | 1 | 0 | 0 | 1 |
| 3 | NULL | 1 | NULL | NULL | 1 | NULL |
+----+------+---------+-------------+------+-------------+-----------+
E'tibor bering: uchinchi qatorda izoh = '' natijasi 0 yoki 1
emas, balki NULL.
Uch qiymatli mantiq #
SELECT
1 = 1 AS rost,
1 = 2 AS yolgon,
1 = NULL AS tenglik,
NULL = NULL AS null_tenglik,
NULL <> NULL AS null_tengsizlik,
NULL IS NULL AS is_null;
+------+--------+---------+--------------+-----------------+---------+
| rost | yolgon | tenglik | null_tenglik | null_tengsizlik | is_null |
+------+--------+---------+--------------+-----------------+---------+
| 1 | 0 | NULL | NULL | NULL | 1 |
+------+--------+---------+--------------+-----------------+---------+
NULL = NULL rost emasBu SQL dagi eng ko'p chalkashtiriladigan qoida.
NULL "noma'lum" degani. Ikki noma'lum qiymat teng bo'lishi ham,
bo'lmasligi ham mumkin - shuning uchun javob "noma'lum",
ya'ni yana NULL.
Amaliy oqibat:
-- HECH QACHON qator qaytarmaydi
SELECT * FROM sinov WHERE izoh = NULL;
-- To'g'ri
SELECT * FROM sinov WHERE izoh IS NULL;
Shuning uchun SQL da IS NULL va IS NOT NULL operatorlari
bor - oddiy = ishlamaydi.
MariaDB da qo'shimcha operator ham mavjud:
izoh <=> NULL -- "NULL-xavfsiz tenglik", NULL uchun 1 qaytaradi
Bu standart SQL emas, lekin MySQL/MariaDB da qulay.
WHERE da NULL yo'qoladi #
SELECT id, son FROM sinov WHERE son <> 10 ORDER BY id;
+----+------+
| id | son |
+----+------+
| 2 | 0 |
+----+------+
son = NULL bo'lgan qator chiqmadi, garchi u 10 ga teng
bo'lmasa ham.
-- NULL ni ham qo'shish uchun aniq yozish kerak
SELECT id, son FROM sinov WHERE son <> 10 OR son IS NULL ORDER BY id;
+----+------+
| id | son |
+----+------+
| 2 | 0 |
| 3 | NULL |
+----+------+
NOT IN va NULL - jimgina yo'qoladigan natijaBu tuzoq juda ko'p xatoga sabab bo'lgan:
SELECT * FROM talabalar
WHERE id NOT IN (SELECT talaba_id FROM chetlashtirilganlar);
Agar chetlashtirilganlar.talaba_id da bitta NULL bo'lsa,
bu so'rov hech qanday qator qaytarmaydi.
Sabab: x NOT IN (1, 2, NULL) aslida
x <> 1 AND x <> 2 AND x <> NULL - oxirgisi NULL beradi,
AND esa NULL bilan hech qachon TRUE bo'lmaydi.
Uch yechim:
-- 1. NULL larni chiqarib tashlash
WHERE id NOT IN (SELECT talaba_id FROM chetlashtirilganlar
WHERE talaba_id IS NOT NULL)
-- 2. NOT EXISTS ishlatish (eng ishonchli)
WHERE NOT EXISTS (SELECT 1 FROM chetlashtirilganlar c
WHERE c.talaba_id = talabalar.id)
-- 3. Ustunni NOT NULL qilish
NOT EXISTS afzal - u NULL ga befarq va odatda tezroq
ham ishlaydi.
Agregatsiyada NULL #
CREATE TABLE ballar (
id INT PRIMARY KEY AUTO_INCREMENT,
talaba VARCHAR(50) NOT NULL,
ball INT
);
INSERT INTO ballar (talaba, ball) VALUES
('Husanboy', 90),
('Malika', 80),
('Kamola', NULL),
('Nodira', NULL);
SELECT
COUNT(*) AS qatorlar,
COUNT(ball) AS ballar_soni,
SUM(ball) AS yigindi,
AVG(ball) AS ortacha,
MIN(ball) AS eng_kam,
MAX(ball) AS eng_kop
FROM ballar;
+----------+-------------+---------+---------+---------+---------+
| qatorlar | ballar_soni | yigindi | ortacha | eng_kam | eng_kop |
+----------+-------------+---------+---------+---------+---------+
| 4 | 2 | 170 | 85.0000 | 80 | 90 |
+----------+-------------+---------+---------+---------+---------+
NULL ni tashlab yuboradi| Funksiya | NULL bilan |
|---|---|
COUNT(*) | Barcha qatorni sanaydi |
COUNT(ustun) | NULL larni sanamaydi |
SUM, AVG, MIN, MAX | NULL larni e'tiborsiz qoldiradi |
Bu AVG da muhim oqibatga ega:
AVG(ball) = 170 / 2 = 85 -- NULL lar hisobga olinmadi
Agar NULL ni nol deb hisoblash kerak bo'lsa, aniq
aytishingiz kerak:
SELECT AVG(COALESCE(ball, 0)) FROM ballar; -- 170 / 4 = 42.5
Qaysi biri to'g'ri - biznes savoli:
| Savol | To'g'ri hisob |
|---|---|
| "Baho olganlarning o'rtachasi" | AVG(ball) |
| "Sinfning o'rtacha bahosi" | AVG(COALESCE(ball, 0)) |
Bo'sh jadvalda esa SUM 0 emas, NULL qaytaradi:
SELECT COALESCE(SUM(ball), 0) FROM ballar WHERE 1 = 0; -- 0
Shuning uchun SUM natijasini deyarli har doim COALESCE
bilan o'rash kerak.
NULL bilan ishlash funksiyalari #
SELECT
talaba,
ball,
COALESCE(ball, 0) AS nol_bilan,
IFNULL(ball, -1) AS ifnull_bilan,
NULLIF(ball, 90) AS nullif_90,
CASE WHEN ball IS NULL THEN 'topshirmagan'
ELSE CAST(ball AS CHAR) END AS holat
FROM ballar
ORDER BY id;
+----------+------+-----------+--------------+-----------+--------------+
| talaba | ball | nol_bilan | ifnull_bilan | nullif_90 | holat |
+----------+------+-----------+--------------+-----------+--------------+
| Husanboy | 90 | 90 | 90 | NULL | 90 |
| Malika | 80 | 80 | 80 | 80 | 80 |
| Kamola | NULL | 0 | -1 | NULL | topshirmagan |
| Nodira | NULL | 0 | -1 | NULL | topshirmagan |
+----------+------+-----------+--------------+-----------+--------------+
| Funksiya | Vazifasi |
|---|---|
COALESCE(a, b, c) | Birinchi NULL bo'lmagan qiymat |
IFNULL(a, b) | a NULL bo'lsa b (MySQL/MariaDB) |
NULLIF(a, b) | a = b bo'lsa NULL, aks holda a |
NULLIF - nolga bo'lishdan himoyaSELECT jami / NULLIF(soni, 0) AS ortacha FROM hisobot;
soni nol bo'lsa, NULLIF uni NULL ga aylantiradi va
natija NULL bo'ladi - xato o'rniga.
MariaDB da nolga bo'lish odatda NULL beradi, lekin qat'iy
rejimda xato bo'lishi mumkin. NULLIF har ikkala holatda
ham ishonchli.
COALESCE esa standart SQL, IFNULL faqat MySQL/MariaDB da
bor - portativ kod uchun COALESCE ishlating.
UNIQUE va NULL #
CREATE TABLE foydalanuvchilar (
id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(100) UNIQUE,
telefon VARCHAR(20) UNIQUE
);
INSERT INTO foydalanuvchilar (email, telefon) VALUES
('[email protected]', '901234567'),
('[email protected]', NULL),
('[email protected]', NULL),
(NULL, '911112233');
SELECT id, COALESCE(email, '(null)') AS email,
COALESCE(telefon, '(null)') AS telefon
FROM foydalanuvchilar
ORDER BY id;
+----+--------+-----------+
| id | email | telefon |
+----+--------+-----------+
| 1 | [email protected] | 901234567 |
| 2 | [email protected] | (null) |
| 3 | [email protected] | (null) |
| 4 | (null) | 911112233 |
+----+--------+-----------+
UNIQUE bir nechta NULL ga ruxsat beradiIkkita qatorda telefon NULL - va UNIQUE cheklov
e'tiroz bildirmadi.
Sabab yana o'sha: NULL = NULL rost emas, shuning uchun
ma'lumotlar bazasi ularni takror deb hisoblamaydi.
Bu standart SQL xatti-harakati va odatda foydali:
pasport VARCHAR(9) UNIQUE -- hammada ham bo'lmasligi mumkin
Lekin ba'zan bu kutilmagan bo'ladi. "Faqat bitta NULL" kerak
bo'lsa, uni cheklov bilan ifodalab bo'lmaydi - NOT NULL
qilib, "yo'q" ma'nosini boshqa qiymat bilan bering:
holat ENUM('faol', 'nofaol', 'nomalum') NOT NULL DEFAULT 'nomalum'
Diqqat: birlamchi kalit NULL ni umuman qabul qilmaydi -
u avtomatik NOT NULL.
NULL va tartiblash #
SELECT talaba, ball FROM ballar ORDER BY ball ASC;
+----------+------+
| talaba | ball |
+----------+------+
| Kamola | NULL |
| Nodira | NULL |
| Malika | 80 |
| Husanboy | 90 |
+----------+------+
-- NULL larni oxiriga surish
SELECT talaba, ball
FROM ballar
ORDER BY ball IS NULL, ball ASC;
+----------+------+
| talaba | ball |
+----------+------+
| Malika | 80 |
| Husanboy | 90 |
| Kamola | NULL |
| Nodira | NULL |
+----------+------+
NULL tartibi standartlashtirilmaganMySQL/MariaDB da NULL eng kichik hisoblanadi - ASC da
boshida, DESC da oxirida turadi.
PostgreSQL da esa aksincha - NULL eng katta.
Standart SQL da NULLS FIRST / NULLS LAST bor, lekin
MySQL/MariaDB uni qo'llab-quvvatlamaydi. Yuqoridagi hiyla
ishlatiladi:
ORDER BY ball IS NULL, ball -- NULL lar oxirida
ORDER BY ball IS NOT NULL, ball -- NULL lar boshida
ball IS NULL 0 yoki 1 qaytaradi, shuning uchun u
birinchi saralash mezoni bo'lib xizmat qiladi.
Foydalanuvchiga ko'rsatiladigan ro'yxatda NULL lar odatda
oxirida bo'lishi kutiladi - buni aniq yozing.
NULL ni qachon ishlatish kerak #
NULL yoki standart qiymat?| Holat | Qaror |
|---|---|
| Qiymat haqiqatan noma'lum | NULL |
| Qiymat hali kiritilmagan | NULL |
| Qiymat qo'llanmaydi | NULL |
| "Nol" mazmunli qiymat | 0, NULL emas |
| "Bo'sh" mazmunli qiymat | '', NULL emas |
| Har doim qiymat bo'ladi | NOT NULL |
Misollar:
tugilgan_sana DATE NULL -- bilmasligimiz mumkin
oxirgi_kirish DATETIME NULL -- hali kirmagan bo'lishi mumkin
qoldiq DECIMAL NOT NULL DEFAULT 0 -- nol - haqiqiy qiymat
izoh TEXT NULL -- yozilmagan bo'lishi mumkin
faolmi BOOLEAN NOT NULL DEFAULT TRUE
NULL ga ruxsat berish narxi bor:
- Har so'rovda
IS NULLhaqida o'ylash kerak; NOT IN,<>,JOINda tuzoqlar paydo bo'ladi;- Ilova kodida
nulltekshiruvi kerak; - Indeks samaradorligi biroz pasayadi.
Shuning uchun imkon bo'lsa NOT NULL qo'ying. 2-bo'limda
aytilganidek, keyinchalik bo'shatish oson, qattiqlashtirish
qiyin.
Amaliy tekshiruv #
SELECT
COUNT(*) AS jami,
SUM(ball IS NULL) AS ballsiz,
ROUND(100.0 * SUM(ball IS NULL) / COUNT(*), 1) AS foiz
FROM ballar;
+------+---------+------+
| jami | ballsiz | foiz |
+------+---------+------+
| 4 | 2 | 50.0 |
+------+---------+------+
NULL,0va''ni bir jadvalda taqqoslang.izoh = NULLnima uchun ishlamasligini tushuntiring.WHERE son <> 10NULLqatorni tashlab ketishini ko'ring.NOT INvaNULLtuzog'ini takrorlang.NOT EXISTSbilan uni tuzating.COUNT(*)vaCOUNT(ustun)farqini ko'rsating.AVGNULLlarni tashlashini isbotlang.COALESCE,IFNULL,NULLIFni sinang.UNIQUEbir nechtaNULLga ruxsat berishini tekshiring.NULLlarni tartibda oxiriga suring.
Xulosa #
NULL- "noma'lum",0yoki''emas.NULL = NULLrost emas -IS NULLishlating.WHEREdaNULLqatorlar jimgina tushib qoladi.NOT IN+NULL= hech qanday natija;NOT EXISTSishlating.COUNT(*)hammasini,COUNT(ustun)faqatNULLbo'lmaganini sanaydi.SUM,AVG,MIN,MAXNULLlarni tashlab yuboradi.- Bo'sh natijada
SUMNULLqaytaradi -COALESCEbilan o'rang. UNIQUEbir nechtaNULLga ruxsat beradi.NULLtartibi tizimga bog'liq - aniq yozing.- Imkon bo'lsa
NOT NULL-NULLning narxi bor.
Keyingi bo'limda cheklovlar bilan ma'lumot sifatini ta'minlashni ko'ramiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.