6-bo‘lim
SELECT ning kuchli tomonlari
DISTINCT ON, NULL bilan to'g'ri ishlash, COALESCE va NULLIF, ORDER BY da NULLS FIRST, sahifalashda OFFSET muammosi.
Ushbu bo‘lim mundarijasi
Bu bo'limda SELECT ning PostgreSQL ga xos imkoniyatlarini
ko'ramiz. Ular ko'p yozuvni qisqartiradi va ba'zi klassik
xatolarning oldini oladi.
CREATE TABLE ijara (
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
oquvchi text NOT NULL,
kitob text NOT NULL,
olingan date NOT NULL,
qaytargan date
);
INSERT INTO ijara (oquvchi, kitob, olingan, qaytargan) VALUES
('Husanboy', 'O''tkan kunlar', '2026-01-10', '2026-01-24'),
('Husanboy', 'Kecha va kunduz', '2026-02-05', NULL),
('Husanboy', 'Mehrobdan chayon', '2026-03-01', '2026-03-12'),
('Malika', 'O''tkan kunlar', '2026-01-15', '2026-01-20'),
('Malika', 'Urush va tinchlik', '2026-02-20', NULL),
('Nodira', 'Kecha va kunduz', '2026-03-05', '2026-03-18');
DISTINCT ON - guruhning birinchi qatori #
Klassik vazifa: "har bir o'quvchining eng oxirgi ijarasini ko'rsat".
Ko'p bazalarda buni yozish uchun ichki so'rov yoki oyna funksiyasi kerak. PostgreSQL da esa:
SELECT DISTINCT ON (oquvchi) oquvchi, kitob, olingan
FROM ijara
ORDER BY oquvchi, olingan DESC;
oquvchi | kitob | olingan
----------+-------------------+------------
Husanboy | Mehrobdan chayon | 2026-03-01
Malika | Urush va tinchlik | 2026-02-20
Nodira | Kecha va kunduz | 2026-03-05
(3 rows)
Qoida ikkita va ular birga ishlaydi:
| Qism | Vazifasi |
|---|---|
DISTINCT ON (oquvchi) | Har oquvchi uchun bitta qator qoldiradi |
ORDER BY oquvchi, olingan DESC | Qaysi qator qolishini belgilaydi |
ORDER BY ning boshi DISTINCT ON bilan bir xil bo'lishi shartBu eng ko'p uchraydigan xato. ORDER BY da birinchi ustun
DISTINCT ON dagi ustun bo'lmasa, PostgreSQL xato beradi.
Mantiq oddiy: baza avval qatorlarni tartiblaydi, keyin har guruhdan birinchisini oladi. Tartiblash guruh bo'yicha boshlanmasa, "birinchi" tushunchasi ma'nosini yo'qotadi.
Ikkinchi ustun esa siz tanlaysiz: olingan DESC - eng
yangisi, olingan ASC - eng eskisi.
NULL bilan ishlash #
NULL - bu "noma'lum". Uning bilan taqqoslash har doim
NULL beradi, hatto o'zi bilan ham:
SELECT NULL = NULL AS oddiy_tenglik,
NULL IS NULL AS is_null,
NULL IS NOT DISTINCT FROM NULL AS aqlli_tenglik,
1 IS DISTINCT FROM NULL AS farq_qiladimi;
oddiy_tenglik | is_null | aqlli_tenglik | farq_qiladimi
---------------+---------+---------------+---------------
| t | t | t
(1 row)
IS NOT DISTINCT FROM - bu "NULL ni ham hisobga oladigan
tenglik". Ikkala tomon NULL bo'lsa, u rost beradi.
Amalda bu qaytarilmagan kitoblarni topishda kerak bo'ladi:
SELECT oquvchi, kitob
FROM ijara
WHERE qaytargan IS NULL
ORDER BY oquvchi;
oquvchi | kitob
----------+-------------------
Husanboy | Kecha va kunduz
Malika | Urush va tinchlik
(2 rows)
= NULL hech qachon ishlamaydiBu xatoni hamma qiladi:
WHERE qaytargan = NULL
Bu so'rov hech qachon qator qaytarmaydi. Xato ham bermaydi - shunchaki bo'sh natija.
Sabab: qaytargan = NULL ifodasi NULL ga teng, NULL esa
WHERE uchun "rost emas" degani.
To'g'ri yozuv har doim IS NULL yoki IS NOT NULL.
Xuddi shu sabab bilan NOT IN ro'yxatida NULL bo'lsa,
so'rov jimgina bo'sh natija beradi - bu ancha nozik tuzoq.
COALESCE va NULLIF #
COALESCE birinchi NULL bo'lmagan qiymatni qaytaradi:
SELECT oquvchi,
kitob,
COALESCE(qaytargan::text, 'hali qaytarilmagan') AS holat
FROM ijara
WHERE oquvchi = 'Husanboy'
ORDER BY olingan;
oquvchi | kitob | holat
----------+------------------+--------------------
Husanboy | O'tkan kunlar | 2026-01-24
Husanboy | Kecha va kunduz | hali qaytarilmagan
Husanboy | Mehrobdan chayon | 2026-03-12
(3 rows)
NULLIF esa teskarisi - ikki qiymat teng bo'lsa NULL
qaytaradi. U nolga bo'lishdan himoya qilishda qulay:
SELECT 100 / NULLIF(0, 0) AS xavfsiz,
COALESCE(100 / NULLIF(0, 0), -1) AS standart_bilan;
xavfsiz | standart_bilan
---------+----------------
| -1
(1 row)
Agar NULLIF bo'lmaganda, 100 / 0 xato berib, butun so'rov
to'xtardi. Endi esa NULL qaytdi va uni COALESCE bilan
almashtirish mumkin.
ORDER BY va NULL #
Saralashda NULL qayerga tushadi? PostgreSQL da standart
qoida bor, lekin uni o'zgartirish mumkin:
SELECT oquvchi, kitob, qaytargan
FROM ijara
ORDER BY qaytargan DESC NULLS LAST, oquvchi;
oquvchi | kitob | qaytargan
----------+-------------------+------------
Nodira | Kecha va kunduz | 2026-03-18
Husanboy | Mehrobdan chayon | 2026-03-12
Husanboy | O'tkan kunlar | 2026-01-24
Malika | O'tkan kunlar | 2026-01-20
Husanboy | Kecha va kunduz |
Malika | Urush va tinchlik |
(6 rows)
Oxirgi ikki qatorga qarang: qaytargan bo'sh bo'lganlar
oxirida turibdi - biz shuni so'radik.
| Yozuv | NULL qayerda |
|---|---|
ORDER BY x ASC | oxirida (standart) |
ORDER BY x DESC | boshida (standart) |
ORDER BY x NULLS FIRST | boshida |
ORDER BY x NULLS LAST | oxirida |
Standart qoida chalkash, shuning uchun muhim hisobotlarda
NULLS FIRST yoki NULLS LAST ni ochiq yozing.
Sahifalash #
LIMIT va OFFSET oddiy va tanish:
SELECT id, oquvchi, kitob
FROM ijara
ORDER BY id
LIMIT 3 OFFSET 2;
id | oquvchi | kitob
----+----------+-------------------
3 | Husanboy | Mehrobdan chayon
4 | Malika | O'tkan kunlar
5 | Malika | Urush va tinchlik
(3 rows)
OFFSET yetarliHamma joyda kalit bo'yicha sahifalashga o'tish shart emas.
| Holat | Tavsiya |
|---|---|
| Admin panel, 10-20 sahifa | OFFSET mos |
| Cheksiz aylantirish | Kalit bo'yicha |
| Millionlab qator, chuqur sahifalar | Kalit bo'yicha |
| Eksport (hammasini o'qish) | Kursor yoki kalit bo'yicha |
OFFSET ning yana bir kamchiligi bor: sahifalar orasida yangi
qator qo'shilsa, ba'zi yozuvlar ikki marta ko'rinadi yoki
tushib qoladi. Kalit bo'yicha usulda bu muammo yo'q.
- Har o'quvchining eng eski ijarasini
DISTINCT ONbilan toping. - Buning uchun
ORDER BYda nimani o'zgartirish kerak? ORDER BYdanoquvchini olib tashlang - qanday xato chiqdi?NULL = NULLvaNULL IS NULLfarqini yozing.WHERE qaytargan = NULLni sinang va natijani izohlang.COALESCEbilan bo'sh qiymatga matn qo'ying.NULLIFyordamida nolga bo'lishdan himoyalaning.NULLS FIRSTvaNULLS LASTnatijalarini solishtiring.OFFSETnima uchun katta sahifalarda sekinlashishini tushuntiring.- Kalit bo'yicha sahifalashning kamchiligini yozing.
Xulosa #
DISTINCT ONhar guruhdan bitta qator qoldiradi - qaysinisiORDER BYbilan hal qilinadi.ORDER BYning birinchi ustuniDISTINCT ONdagi ustun bilan bir xil bo'lishi shart.NULL- "noma'lum"; u hech narsa bilan, hatto o'zi bilan ham teng emas.= NULLhech qachon ishlamaydi - har doimIS NULLyozing.IS NOT DISTINCT FROM-NULLni ham hisobga oladigan tenglik.COALESCEbirinchiNULLbo'lmagan qiymatni qaytaradi.NULLIFnolga bo'lishdan himoya qilishning eng ixcham yo'li.- Saralashda
NULLning o'rniniNULLS FIRST/NULLS LASTbilan aniq belgilang. - Katta
OFFSETsekin: baza tashlab yuboradigan qatorlarni ham o'qiydi. - Chuqur sahifalash uchun kalit bo'yicha usul ishlatiladi.
Keyingi bo'limda jadvallarni birlashtiramiz va PostgreSQL ning
LATERAL imkoniyati bilan tanishamiz.
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.