Mundarija (31)
- Bu darsda
- 1. Nega bu kerak?
- 2. NULL — "noma'lum"
- 2.1 JavaScript bilan farqi
- 2.2 psql'da NULL'ni ko'rinadigan qilish
- 2.3 Noma'lum bilan har amal — noma'lum
- 3. Uch qiymatli mantiq
- 3.1 Jadval
- 3.2 WHERE faqat true'ni o'tkazadi
- 4. NULL bilan to'g'ri ishlash
- 4.1 = NULL emas, IS NULL
- 4.2 IS DISTINCT FROM — NULL'ni ham hisobga oladigan "teng emas"
- 4.3 COALESCE va NULLIF
- 5. NOT IN tuzog'i
- 5.1 Tuzoq amalda
- 5.2 Sababi: NOT IN — bu AND zanjiri
- 5.3 Yechim: NOT EXISTS
- 6. NULL boshqa joylarda
- 6.1 Agregatlar NULL'ni tashlab ketadi
- 6.2 CHECK NULL'ni o'tkazadi
- 6.3 UNIQUE va NULL
- 6.4 Tartiblash va tashqi kalit
- 7. SQL qadami: NULL va bizning sxema (holat 15, commit yo'q)
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): natijani toping
- 2-mashq (o'rta): telefonlar
- 3-mashq (qiyin): eslatma olmaganlar
- 10. Real ishda
- Xulosa
- Manbalar
SQL NULL mantiqi: uch qiymatli mantiq, IS NULL, COALESCE va NOT IN tuzog'i
Qisqacha: SQL'da
NULL— "qiymat noma'lum" degani, nol ham, bo'sh satr ham emas. Noma'lum narsa bilan har qanday taqqoslash (NULL = NULLham) yana noma'lum —NULLberadi,WHEREesa faqattrueni o'tkazadi. Shuning uchun= NULLemas,IS NULL; "teng emas, NULL ham hisobga" uchun —IS DISTINCT FROM.COALESCEbo'sh qiymat o'rniga zaxira beradi. Eng xavfli tuzoq:NOT INro'yxatida bittaNULLbo'lsa, natija doim bo'sh — o'rnigaNOT EXISTSishlating.
Bu darsda
NULLnima ekanini va JavaScript'daginulldan farqini tushuntira olasiz.- Uch qiymatli mantiq (
true,false,NULL) jadvalini bilasiz vaWHEREga ta'sirini oldindan aytasiz. IS NULL,IS DISTINCT FROM,COALESCE,NULLIFni to'g'ri ishlatasiz.NOT IN+NULLtuzog'ini tanib,NOT EXISTSbilan almashtirasiz.- Agregatlar,
CHECK,UNIQUEvaORDER BYNULLbilan qanday ishlashini bilasiz.
Oldin bilishingiz kerak: SELECT va WHERE, ORDER BY, LIMIT va OFFSET, CREATE TABLE va cheklovlar.
1. Nega bu kerak?
SELECT va WHERE darsida NOT IN haqida "ro'yxatda NULL bo'lsa — natija doim bo'sh" deb ogohlantirgan edik. ORDER BY darsida NULL saralashda "eng katta" bo'lib chiqdi. Endi buning sababini tushunamiz.
Hayotiy vaziyat. Ro'yxatdan o'tishda telefon raqami ixtiyoriy. Malika uni kiritmadi. Bazada uning telefoni nima bo'lishi kerak?
''(bo'sh satr) — "telefoni bor, u bo'sh" degan g'alati gap.'0'— "telefoni 0" — yolg'on.NULL— "bilmaymiz". Aynan shu.
Muammo shundaki, "bilmaymiz" bilan hisoblash odatiy mantiqdan boshqacha ishlaydi. "Malikaning telefoni Azizniki bilan bir xilmi?" — Javob "ha" ham, "yo'q" ham emas, "bilmaymiz". SQL ham aynan shunday javob beradi. Va bu ko'p dasturchini chalg'itadi: so'rov xatosiz ishlaydi, lekin bir qism qatorlar jim yo'qoladi.
O'xshatish: yopiq konvert. Ikki konvertda pul bor, lekin ochilmagan. "Ikkalasida bir xil pulmi?" — bilmaysiz. "Birinchisida 100 000 so'mdan ko'pmi?" — bilmaysiz. Konvertni ochmaguningizcha har savolga javob — "noma'lum".
2. NULL — "noma'lum"
2.1 JavaScript bilan farqi
JavaScript'da null === null — true. SQL'da esa NULL = NULL — true emas. Kanon (PostgreSQL 18.6):
SELECT NULL = NULL AS teng,
NULL <> 1 AS farq,
NULL IS NULL AS isnull,
true AND NULL AS va,
true OR NULL AS yoki,
NOT NULL::boolean AS emas;Natija:
teng | farq | isnull | va | yoki | emas
------+------+--------+----+------+------
| | t | | t |
(1 row)Bo'sh kataklar — NULL. psql uni sukut bo'yicha bo'sh joy qilib ko'rsatadi, shuning uchun ko'rish qiyin. Buni tuzatamiz.
2.2 psql'da NULL'ni ko'rinadigan qilish
\pset null — psql'ga "NULL o'rniga shu belgini chiqar" deydi. Biz ishga tushirdik (PostgreSQL 17.6, Windows 11):
vazifalar=# \pset null '∅'
Null display is "∅".Endi kichik jadvalni chiqaramiz:
SELECT nom, x
FROM (VALUES ('a', 1), ('b', NULL), ('c', 2)) AS t (nom, x);Natija:
nom | x
-----+---
a | 1
b | ∅
c | 2
(3 rows)Endi b ning x i bo'sh satr emas, NULL ekani aniq. Bu darsning qolgan "biz ishga tushirdik" chiqishlarida ∅ — NULL. Doimiy qilish uchun \pset null '∅' ni .psqlrc ga yozing (psql chuqur). Kanon chiqishlarida esa NULL — bo'sh joy.
2.3 Noma'lum bilan har amal — noma'lum
Taqqoslashgina emas, deyarli har amal NULL bilan NULL beradi. Biz ishga tushirdik (PostgreSQL 17.6):
SELECT 'Aziz' || NULL AS ulash,
NULL + 1 AS qoshish,
length(NULL) AS uzunlik;Natija:
ulash | qoshish | uzunlik
-------+---------+---------
∅ | ∅ | ∅
(1 row)"Aziz + noma'lum narsa" — noma'lum. JavaScript'dagi "Aziz" + null → "Aziznull" kabi g'alati natija yo'q, lekin NULL "yuqumli": u ifoda bo'ylab tarqaladi. (concat funksiyasi bundan istisno — Ifodalar va o'rnatilgan funksiyalar darsida.)
3. Uch qiymatli mantiq
3.1 Jadval
SQL'da mantiqiy qiymat uchta: true, false va NULL (unknown — noma'lum). AND va OR uchun qoida: "noma'lumni true deb ham, false deb ham tasavvur qiling. Ikkala holatda javob bir xil chiqsa — o'sha javob, aks holda — NULL".
| A | B | A AND B | A OR B |
|---|---|---|---|
| true | NULL | NULL | true |
| false | NULL | false | NULL |
| NULL | NULL | NULL | NULL |
Misol: false AND NULL. NULL true bo'lsa ham, false bo'lsa ham false AND … — false. Demak javob aniq: false. true AND NULL esa noma'lumga bog'liq — NULL. NOT NULL — NULL (noma'lumning teskarisi ham noma'lum).
3.2 WHERE faqat true'ni o'tkazadi
Bu eng muhim qoida. WHERE qatorni natijaga faqat shart aniq true bo'lsa qo'shadi. false ham, NULL ham — tashlanadi.
flowchart LR
A["Qator"] --> B{"WHERE sharti"}
B -->|true| C["Natijaga kiradi"]
B -->|false| D["Tashlanadi"]
B -->|NULL| DDiagrammaga qarang: NULL va false bir xil yo'ldan ketadi. Kanon (PostgreSQL 18.6) — "x 1 ga teng bo'lmaganlar":
SELECT nom
FROM (VALUES ('a', 1), ('b', NULL), ('c', 2)) AS t (nom, x)
WHERE x <> 1;Natija:
nom
-----
c
(1 row)b qani? Uning x i noma'lum. "Noma'lum 1 ga teng emasmi?" — noma'lum. WHERE uni tashladi. Odam mantiqi bilan b "1 emas" — lekin SQL buni bilmaydi.
Yana bir g'alati misol. Biz ishga tushirdik (PostgreSQL 17.6, holat 15):
SELECT count(*) FROM vazifalar
WHERE NOT (bajarildi AND NULL);Natija:
count
-------
20
(1 row)40 qatordan 20 tasi. Bajarilmaganlarda: false AND NULL = false, NOT false = true — o'tdi. Bajarilganlarda: true AND NULL = NULL, NOT NULL = NULL — tashlandi. Haqiqiy so'rovda NULL doimiy emas, nullable ustundan keladi — va xuddi shunday jim "yo'qotadi".
Tekshirib ko'ring:
WHERE x = 1 OR x <> 1hamma qatorni qaytaradimi?
Javob
Yo'q — x NULL bo'lgan qatorlardan tashqari hammasini. NULL = 1 — NULL, NULL <> 1 — NULL, NULL OR NULL — NULL. "Yoki teng, yoki teng emas" odam uchun doim rost, SQL uchun esa NULL da emas.
4. NULL bilan to'g'ri ishlash
4.1 = NULL emas, IS NULL
Boshlovchining eng birinchi xatosi. Biz ishga tushirdik (PostgreSQL 17.6):
SELECT nom
FROM (VALUES ('a', 1), ('b', NULL), ('c', 2)) AS t (nom, x)
WHERE x = NULL;
SELECT nom
FROM (VALUES ('a', 1), ('b', NULL), ('c', 2)) AS t (nom, x)
WHERE x IS NULL;Natija:
nom
-----
(0 rows)
nom
-----
b
(1 row)x = NULL — har qatorda NULL, demak hech narsa topilmaydi. Xato ham bermaydi — shuning uchun xavfli. IS NULL va IS NOT NULL — maxsus operatorlar, ular doim true yoki false qaytaradi, hech qachon NULL emas.
4.2 IS DISTINCT FROM — NULL'ni ham hisobga oladigan "teng emas"
"x 1 dan farqli bo'lganlar, NULL ham kirsin" — buni x <> 1 OR x IS NULL deb yozish mumkin. Qisqasi — IS DISTINCT FROM. U NULL ni oddiy qiymat deb taqqoslaydi: ikki NULL — "bir xil", NULL va 1 — "har xil". Kanon (PostgreSQL 18.6):
SELECT NULL IS DISTINCT FROM NULL AS distinct_null,
1 IS DISTINCT FROM NULL AS distinct_1;
SELECT nom
FROM (VALUES ('a', 1), ('b', NULL), ('c', 2)) AS t (nom, x)
WHERE x IS DISTINCT FROM 1;Natija:
distinct_null | distinct_1
---------------+------------
f | t
(1 row)
nom
-----
b
c
(2 rows)Endi b ham bor. Teskarisi — IS NOT DISTINCT FROM: NULL ni ham hisobga oladigan "teng". Bu, masalan, "qiymat o'zgardimi?" degan tekshiruvda kerak: eski NULL, yangi NULL — o'zgarmadi; eski NULL, yangi 5 — o'zgardi. Oddiy <> ikkala holatda ham NULL berardi. Bu Soft delete va tarix jadvallari darsidagi trigger'larda kerak bo'ladi.
4.3 COALESCE va NULLIF
coalesce(a, b, c) — birinchi NULL bo'lmagan qiymat. JavaScript'dagi a ?? b ?? c ga o'xshaydi. nullif(a, b) — teskarisi: a = b bo'lsa NULL, aks holda a. Kanon (PostgreSQL 18.6):
SELECT coalesce(NULL, NULL, 'zaxira') AS coalesce,
nullif(0, 0) AS nullif,
10 / nullif(0, 0) AS nolga_bolish_yoq;Natija:
coalesce | nullif | nolga_bolish_yoq
----------+--------+------------------
zaxira | |
(1 row)Uchinchi ustunga qarang: 10 / 0 xato (division by zero) bergan bo'lardi (UPDATE va DELETE xavfsiz darsida ko'rdik). 10 / nullif(0, 0) = 10 / NULL = NULL — xato yo'q. Hisobotlarda "o'rtacha = jami / soni" da soni nol bo'lishi mumkin bo'lsa — shu naqsh.
COALESCE ning odatiy ishi — ko'rsatish uchun zaxira matn: coalesce(telefon, 'kiritilmagan'). Mashqlarda buni qilamiz.
Tekshirib ko'ring:
coalesce(NULL, 0, 5)vanullif('a', 'b')nima qaytaradi?
Javob
0 — birinchi NULL bo'lmagani (0 ham qiymat, NULL emas). 'a' — 'a' va 'b' teng emas, shuning uchun birinchisi qaytadi.
5. NOT IN tuzog'i
5.1 Tuzoq amalda
Savol: "Hali vazifasi yo'q foydalanuvchilar". Bir usul: foydalanuvchining id si vazifalardagi egasi_id lar ro'yxatida yo'q. Kanon (PostgreSQL 18.6):
SELECT id FROM foydalanuvchilar
WHERE id NOT IN (SELECT egasi_id FROM vazifalar);Natija:
id
----
8
(1 row)Shahnoza (8) — to'g'ri. Qavs ichidagi SELECT — ichki so'rov: u 40 ta egasi_id ro'yxatini beradi (Subquery va LATERAL darsida to'liq). Endi ro'yxatda bitta NULL bo'lsin. Kanon (PostgreSQL 18.6):
SELECT id FROM foydalanuvchilar
WHERE id NOT IN (1, 2, 3, 4, 5, 6, 7, NULL);Natija:
id
----
(0 rows)Shahnoza yo'qoldi. Hech kim yo'q. Nega?
5.2 Sababi: NOT IN — bu AND zanjiri
x NOT IN (a, b, c) aslida x <> a AND x <> b AND x <> c. Shahnoza uchun:
flowchart TD
A["8 NOT IN (1, …, 7, NULL)"] --> B["8 <> 1 AND … AND 8 <> 7<br/>AND 8 <> NULL"]
B --> C["true AND … AND true<br/>AND NULL"]
C --> D["NULL"]
D --> E["WHERE tashlaydi"]Diagrammadagi uchinchi qadamga qarang: hamma solishtirish true, faqat oxirgisi NULL. true AND NULL — NULL. Natijada hech bir id uchun shart true bo'lmaydi.
Biz buni alohida ifodalarda ham tekshirdik (PostgreSQL 17.6):
SELECT 3 NOT IN (1, 2) AS bir,
3 NOT IN (1, 2, NULL) AS ikki,
3 IN (1, 2, NULL) AS uch,
1 IN (1, NULL) AS tort;Natija:
bir | ikki | uch | tort
-----+------+-----+------
t | ∅ | ∅ | t
(1 row)IN da NULL kamroq zarar qiladi: topilsa — true (tort), topilmasa — NULL (false o'rniga, lekin WHERE uchun farqi yo'q). NOT IN da esa NULL hamma narsani yo'qotadi.
Haqiqiy hayotda ro'yxat ichki so'rovdan keladi. Bugun egasi_id NOT NULL — tuzoq yo'q. Ertaga kimdir ustundan NOT NULL ni olib tashlaydi yoki boshqa nullable ustun ishlatadi — va so'rov jim "hech kim yo'q" deya boshlaydi. Xato xabari ham, ogohlantirish ham yo'q.
5.3 Yechim: NOT EXISTS
NOT EXISTS — "shunday qator mavjud emas". U har foydalanuvchi uchun alohida tekshiradi va NULL uni chalg'itmaydi. Kanon (PostgreSQL 18.6):
SELECT id FROM foydalanuvchilar f
WHERE NOT EXISTS (
SELECT 1 FROM vazifalar v WHERE v.egasi_id = f.id
);Natija:
id
----
8
(1 row)Bu shablonni Foreign key darsida yetimlarni topishda ishlatgan edik. Qoida: "ro'yxatda yo'q" savoli uchun — NOT EXISTS, NOT IN emas (agar ro'yxat ichki so'rovdan kelsa). NOT IN (1, 2, 3) kabi qo'lda yozilgan, NULL siz ro'yxat xavfsiz.
6. NULL boshqa joylarda
6.1 Agregatlar NULL'ni tashlab ketadi
Bu bo'lim keyingi darsga ko'prik. count, sum, avg kabi agregat funksiyalar ko'p qatorni bitta songa aylantiradi (Agregatlar, GROUP BY va HAVING). Ular NULL ni e'tiborga olmaydi. Kanon (PostgreSQL 18.6):
SELECT count(*) AS hammasi, count(x) AS null_emas,
avg(x) AS ortacha, sum(x) AS yigindi
FROM (VALUES (1), (NULL), (3)) AS t (x);Natija:
hammasi | null_emas | ortacha | yigindi
---------+-----------+--------------------+---------
3 | 2 | 2.0000000000000000 | 4
(1 row)count(*) — qatorlar soni (3). count(x) — x NULL bo'lmagan qatorlar (2). avg = 4 / 2 = 2 — NULL qator bo'luvchiga ham kirmadi. Agar "ma'lumot yo'q"ni nol deb hisoblash kerak bo'lsa — avg(coalesce(x, 0)) = 4 / 3. Qaysi biri to'g'ri — biznes savoli.
Bo'sh to'plamda esa sum — NULL, count — 0. Kanon (PostgreSQL 18.6):
SELECT sum(x) AS bosh_sum, count(x) AS bosh_count
FROM (VALUES (NULL::int)) AS t (x);Natija:
bosh_sum | bosh_count
----------+------------
| 0
(1 row)API'da "jami summa" null bo'lib qaytsa, frontend null.toFixed() da yiqilishi mumkin. coalesce(sum(x), 0) — odatiy himoya.
6.2 CHECK NULL'ni o'tkazadi
CHECK cheklovi qatorni faqat shart false bo'lsa rad etadi. NULL — rad etilmaydi. Biz ishga tushirdik (PostgreSQL 17.6):
CREATE TEMP TABLE t19_c (narx int CHECK (narx > 0));
INSERT INTO t19_c VALUES (NULL);
INSERT INTO t19_c VALUES (-5);Natija:
CREATE TABLE
INSERT 0 1
ERROR: new row for relation "t19_c" violates check constraint "t19_c_narx_check"
DETAIL: Failing row contains (-5).NULL > 0 — NULL, va CHECK uni o'tkazdi. -5 > 0 — false — rad etildi. Bu ataylab shunday: "narx noma'lum" mumkin, "narx manfiy" — yo'q. Narx majburiy bo'lsa — NOT NULL ni alohida yozasiz. WHERE va CHECK qarama-qarshi ishlaydi: WHERE NULL ni tashlaydi, CHECK — o'tkazadi.
6.3 UNIQUE va NULL
UNIQUE uchun ikki NULL "teng" emas (noma'lum va noma'lum — bir xilmi? bilmaymiz). Shuning uchun bir nechta NULL yozish mumkin. PostgreSQL 15 dan NULLS NOT DISTINCT bilan buni o'zgartirsa bo'ladi. Kanon (PostgreSQL 18.6):
CREATE TEMP TABLE t19_a (kod text UNIQUE);
INSERT INTO t19_a VALUES (NULL), (NULL);
SELECT count(*) AS ikki_null_otdi FROM t19_a;
CREATE TEMP TABLE t19_b (kod text UNIQUE NULLS NOT DISTINCT);
INSERT INTO t19_b VALUES (NULL), (NULL);Natija:
CREATE TABLE
INSERT 0 2
ikki_null_otdi
----------------
2
(1 row)
CREATE TABLE
ERROR: duplicate key value violates unique constraint "t19_b_kod_key"
DETAIL: Key (kod)=(null) already exists.Sukut odatda to'g'ri: ixtiyoriy telefon ustuni UNIQUE bo'lsa, telefon kiritmagan ko'p odam bo'lishi kerak. NULLS NOT DISTINCT kamdan-kam kerak: masalan, "har foydalanuvchida ko'pi bilan bitta asosiy (NULL toifali) papka".
6.4 Tartiblash va tashqi kalit
ORDER BYdaNULL— eng katta (ORDER BY, LIMIT va OFFSET),NULLS FIRST/LASTbilan boshqariladi.- Tashqi kalit
NULLni tekshirmaydi — "bog'lanish yo'q" (Foreign key).
Tekshirib ko'ring:
CHECK (chegirma BETWEEN 0 AND 100)bor ustungaNULLyozilsa nima bo'ladi?
Javob
Yoziladi. NULL BETWEEN 0 AND 100 — NULL, CHECK esa faqat false ni rad etadi. Chegirma majburiy bo'lsa, NOT NULL qo'shing (yoki DEFAULT 0).
7. SQL qadami: NULL va bizning sxema (holat 15, commit yo'q)
Holat 15 da hamma ustun NOT NULL — bu ataylab. CREATE TABLE darsidagi qoida: ustun "noma'lum" bo'la olmasa — NOT NULL. Keyingi bosqichlarda ixtiyoriy ustunlar paydo bo'ladi:
| Ustun (qaysi darsda) | NULL ma'nosi |
|---|---|
muddat (ALTER TABLE) |
Muddat belgilanmagan |
bajarilgan_vaqt (ALTER TABLE) |
Hali bajarilmagan |
ota_id (ALTER TABLE) |
Asosiy vazifa (otasi yo'q) |
izohlar.muallif_id (Bog'lanishlar) |
Muallif o'chirilgan |
Har birida NULL ning bitta aniq ma'nosi bor va u sxema izohida yoziladi. "Noma'lum ham, yo'q ham, hali kiritilmagan ham" — bitta NULL ga ko'p ma'no yuklash — keyinchalik xatolar manbai.
API tomonda: JSON'da null → bazada NULL, va aksincha. Lekin "maydon yuborilmadi" (undefined) va "maydonni tozalash" (null) — PATCH so'rovida ikki xil narsa. Buni 25-qism dagi validatsiya bilan farqlaysiz.
8. Ko'p uchraydigan xatolar
| Xato yoki belgi | Sabab | Davosi |
|---|---|---|
WHERE x = NULL — (0 rows) |
= NULL doim NULL |
IS NULL |
<> bilan NULL qatorlar yo'qoldi |
NULL <> 1 — NULL |
IS DISTINCT FROM |
NOT IN (SELECT …) — (0 rows) |
Ro'yxatda NULL bor |
NOT EXISTS |
Matnni NULL bilan ulash — NULL |
NULL yuqumli |
coalesce yoki concat |
division by zero |
Bo'luvchi 0 | x / nullif(y, 0) |
sum NULL qaytardi |
Bo'sh to'plam yoki hammasi NULL |
coalesce(sum(x), 0) |
CHECK bor, lekin NULL yozildi |
CHECK NULL ni o'tkazadi |
NOT NULL qo'shing |
psql'da bo'sh katak — NULL mi, '' mi? |
Ko'rinish bir xil | \pset null '∅' |
9. Mashqlar
1-mashq (oson): natijani toping
Javob — true, false yoki NULL:
NULL = NULL→false AND NULL→true OR NULL→NULL IS NULL→5 NOT IN (1, NULL)→NULL IS DISTINCT FROM 5→
Yechim
- NULL — noma'lumni noma'lum bilan solishtirib bo'lmaydi.
- false —
false ANDhar qanday narsa —false. - true —
true ORhar qanday narsa —true. - true —
IS NULLhech qachonNULLqaytarmaydi. - NULL —
5 <> 1 AND 5 <> NULL=true AND NULL. - true —
IS DISTINCT FROMNULLni oddiy qiymat deb solishtiradi.
2-mashq (o'rta): telefonlar
VALUES jadvali: Aziz '+998 90 000 00 01', Malika NULL, Jasur '+998 91 000 00 02', Dilnoza NULL. Telefoni +998 90 bilan boshlanmaydiganlarni chiqaring — telefoni yo'qlar ham kirsin. Telefon o'rniga NULL bo'lsa "kiritilmagan" yozilsin. Ism bo'yicha tartiblang.
Ishora: NULL NOT LIKE … — NULL. LIKE — SELECT va WHERE.
Yechim
SELECT ism,
coalesce(telefon, 'kiritilmagan') AS telefon
FROM (VALUES ('Aziz', '+998 90 000 00 01'),
('Malika', NULL),
('Jasur', '+998 91 000 00 02'),
('Dilnoza', NULL)) AS t (ism, telefon)
WHERE telefon IS NULL OR telefon NOT LIKE '+998 90%'
ORDER BY ism;Natija (biz ishga tushirdik, PG 17.6):
ism | telefon
---------+-------------------
Dilnoza | kiritilmagan
Jasur | +998 91 000 00 02
Malika | kiritilmagan
(3 rows)telefon IS NULL OR bo'lmasa, Malika va Dilnoza tushib qolardi: ular uchun NOT LIKE — NULL. WHERE dagi telefon — asl ustun (NULL bilan), SELECT dagi coalesce faqat ko'rinishni o'zgartiradi. ORDER BY ism taxallussiz ustun — ism — bo'yicha.
3-mashq (qiyin): eslatma olmaganlar
Holat 15 da vaqtinchalik jadval yarating: eslatmalar (egasi_id bigint, matn text). Unga uchta qator yozing: Aziz (1) va Dilnoza (2) uchun shaxsiy eslatma, va bitta umumiy eslatma — egasi_id NULL. So'ng "shaxsiy eslatma olmagan foydalanuvchilar"ni ikki usulda toping: (a) NOT IN bilan, (b) NOT EXISTS bilan. Natijalarni solishtiring va farqni tushuntiring.
Yechim
CREATE TEMP TABLE eslatmalar (egasi_id bigint, matn text);
INSERT INTO eslatmalar VALUES
(1, 'Dars 19'), (2, 'Dars 19'),
(NULL, 'Hammaga: tizim yangilandi');
-- (a) NOT IN — ro'yxatda NULL bor
SELECT id, ism FROM foydalanuvchilar
WHERE id NOT IN (SELECT egasi_id FROM eslatmalar)
ORDER BY id;
-- (b) NOT EXISTS — to'g'ri javob
SELECT id, ism FROM foydalanuvchilar f
WHERE NOT EXISTS (
SELECT 1 FROM eslatmalar e WHERE e.egasi_id = f.id
)
ORDER BY id;Natija (biz ishga tushirdik, PG 17.6):
CREATE TABLE
INSERT 0 3
id | ism
----+-----
(0 rows)
id | ism
----+--------------------
3 | Sardor Tursunov
4 | Madina Yusupova
5 | Javohir Olimov
6 | Gulnora Saidova
7 | Bekzod Nazarov
8 | Shahnoza Ergasheva
(6 rows)(a) — bo'sh: ichki so'rov {1, 2, NULL} beradi va har id uchun NOT IN — NULL. (b) — 6 kishi, to'g'ri. Umumiy eslatma hech kimga "tegishli" emas, shuning uchun u hech kimni chiqarib tashlamasligi kerak edi. NOT IN ni "tuzatish" ham mumkin (… WHERE egasi_id IS NOT NULL), lekin buni har safar eslab yurish kerak — NOT EXISTS esa doim to'g'ri.
10. Real ishda
- Jim yo'qolgan qatorlar — "hisobotda 3 ta mijoz kam chiqyapti" kabi xatolarning katta qismi
NULLva<>,NOT INyokiLEFT JOINdan keyingiWHEREbilan bog'liq. Kod review'da nullable ustun ko'rsangiz — darhol "NULLbo'lsa nima bo'ladi?" deb so'rang. - ORM va driverlar —
pgNULLni JavaScriptnullga aylantiradi (node-postgres asoslari). TypeScript'da nullable ustun —string | null,NOT NULL—string. SxemadagiNOT NULLfrontendgacha tip xavfsizligini beradi. - Statistika —
avgNULLni tashlaydi: "o'rtacha baho" bo'sh baholarni nol deb hisoblaydimi yoki yo'qmi — mahsulot qarori, uni aniq hal qiling. - Intervyu savollari: "
NULL = NULLnima qaytaradi?", "NOT INvaNOT EXISTSfarqi?", "count(*)vacount(ustun)farqi?" — uchalasi juda ko'p so'raladi.
Xulosa
NULL— "noma'lum": nol ham,''ham emas; deyarli har amalNULLbilanNULLberadi.- Uch qiymatli mantiq:
true,false,NULL;WHEREfaqattrueni o'tkazadi,CHECKesa faqatfalseni rad etadi. IS NULL/IS NOT NULL—= NULLemas;IS DISTINCT FROM—NULLni ham hisobga oladigan solishtirish.coalesce(a, b)— zaxira qiymat;nullif(a, b)— nolga bo'lishdan himoya.NOT INro'yxatida bittaNULL— natija bo'sh; ichki so'rov bilan doimNOT EXISTS.- Agregatlar
NULLni tashlaydi (count(*)≠count(x), bo'shsum—NULL);UNIQUEbir nechtaNULLni o'tkazadi (NULLS NOT DISTINCT— PG 15+).
Keyingi dars: Agregatlar, GROUP BY va HAVING — qatorlarni guruhlab statistika: har foydalanuvchining vazifalari soni, FILTER, HAVING, string_agg va API uchun json_agg.
Manbalar
- PostgreSQL 18 hujjati — Comparison Functions and Operators (
IS NULL,IS DISTINCT FROM) - PostgreSQL 18 hujjati — Logical Operators (uch qiymatli mantiq jadvali)
- PostgreSQL 18 hujjati — Conditional Expressions (
COALESCE,NULLIF) - PostgreSQL 18 hujjati — Subquery Expressions: NOT IN (
NULLhaqida eslatma) - PostgreSQL 18 hujjati — Unique Constraints (
NULLS NOT DISTINCT)
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!