IlmHamroh
JavaScript Full-stack/26-qism. SQL va PostgreSQL17/64-dars17 daqiqa
Mundarija (30)

SQL ORDER BY, LIMIT va OFFSET: tartiblash, sahifalash va barqaror tartib

Qisqacha: SQL natijasining tartibi faqat ORDER BY bilan kafolatlanadi. Usiz tartib tasodifiy. ORDER BY a, b DESC avval a bo'yicha, tenglarni b bo'yicha kamayish tartibida saralaydi. NULL sukut bo'yicha o'sishda oxirida, kamayishda boshida turadi (NULLS FIRST/LAST bilan o'zgartiriladi). LIMIT n OFFSET m — sahifalash; tartib barqaror bo'lishi uchun oxiriga noyob ustun (id) qo'shing. O'zbek alifbosi tartibi uchun — COLLATE "uz-x-icu".

Bu darsda

  • ORDER BY ni bir necha ustun, ASC/DESC, ifoda va taxallus bilan yozasiz.
  • NULL qayerda turishini bilasiz va NULLS FIRST/LAST bilan boshqarasiz.
  • LIMIT/OFFSET bilan sahifalaysiz va FETCH FIRST … WITH TIES farqini tushunasiz.
  • Nega tartib barqaror bo'lishi kerakligini va katta OFFSET nega sekinligini tushuntira olasiz.
  • Ismlarni haqiqiy o'zbek alifbosi bo'yicha saralaysiz.

Oldin bilishingiz kerak: SELECT va WHERE, INSERT va RETURNING.

1. Nega bu kerak?

SELECT va WHERE darsida deyarli har so'rov oxirida ORDER BY id yozdik va "keyingi darsda" dedik. Mana o'sha dars.

Ilovada ro'yxat deyarli doim tartibli ko'rsatiladi: "eng yangi vazifalar tepada", "muddati yaqinlari birinchi". Va deyarli doim — qismlab: Telegram kanali 10 000 xabarni birdaniga yuklamaydi, avval oxirgi 20 tasini ko'rsatadi, pastga tushsangiz — keyingi 20 tasini. Bu sahifalash (pagination).

Ko'pchilik boshlovchilar shunday deb o'ylaydi: "Jadval qanday yozilgan bo'lsa, shunday chiqadi". Yo'q. Relatsion model darsida ko'rdik: jadval — qatorlar to'plami, ro'yxat emas. To'plamda "birinchi" yo'q. PostgreSQL qatorlarni o'zi qulay ko'rgan tartibda qaytaradi. Bugun bir xil chiqishi mumkin, ertaga UPDATE, indeks yoki parallel o'qishdan keyin — boshqacha.

O'xshatish: imtihon natijalari. O'qituvchi ishlarni stolga qanday qo'ygan bo'lsa, shunday tartibda olib qoladi. "Ballar bo'yicha kamayish tartibida, teng ballarda — familiya bo'yicha" desangizgina, ro'yxat har safar bir xil bo'ladi.

2. ORDER BY asoslari

2.1 Bir necha ustun bo'yicha

Bu darsdagi misollar holat 15 bazasida. Kanon (PostgreSQL 18.6):

sql
SELECT egasi_id, bajarildi, matn
FROM vazifalar
ORDER BY egasi_id, bajarildi, yaratilgan_vaqt DESC
LIMIT 6;

Natija:

text
 egasi_id | bajarildi |                       matn                       
----------+-----------+--------------------------------------------------
        1 | f         | Velosiped zanjirini moylash
        1 | f         | SQL JOIN mashqlarini yechish #o'qish
        1 | f         | Oshxonadagi jo'mrakni almashtirish #ta'mir #uy
        1 | f         | Portfolio saytiga blog yozish #portfolio
        1 | f         | JavaScript kursining 26-qismini boshlash #o'qish
        1 | t         | Elektr to'lovini Click orqali qilish #to'lov
(6 rows)

Uch daraja bor, lug'atdagi so'zlar kabi:

  1. Avval egasi_id bo'yicha (o'sish) — Azizning (1) vazifalari tepada.
  2. Bir xil egasi_id ichida — bajarildi bo'yicha: false true dan oldin turadi.
  3. Bir xil holat ichida — yaratilgan_vaqt DESC: eng yangisi birinchi.

ASC (ascending, o'sish) — sukut, yozish shart emas. DESC (descending, kamayish) faqat o'zidan oldingi bitta ustunga tegishli. ORDER BY egasi_id, bajarildi DESC da egasi_id hamon o'sish tartibida.

LIMIT 6 — birinchi 6 ta qator. Keyingi bo'limda batafsil.

2.2 Ifoda, taxallus va raqam

ORDER BY da faqat ustun emas, istalgan ifoda bo'lishi mumkin. Biz ishga tushirdik (PG 17.6, Windows 11) — eng uzun vazifa matnlari:

sql
SELECT id, char_length(matn) AS uzunlik
FROM vazifalar
ORDER BY char_length(matn) DESC, id
LIMIT 3;

Natija:

text
 id | uzunlik 
----+---------
  1 |      48
  2 |      47
 27 |      47
(3 rows)

char_length — belgilar soni (CREATE TABLE darsidagi matn cheklovida ko'rgansiz). 2 va 27 bir xil uzunlikda — ularni ikkinchi ustun (id) tartiblaydi.

SELECT va WHERE darsida WHERE taxallusni bilmasligini ko'rdik. ORDER BY esa SELECT dan keyin bajariladi — u taxallusni biladi. Shuning uchun yuqoridagini ORDER BY uzunlik DESC, id deb ham yozsa bo'ladi.

Ustun raqami ham ishlaydi: ORDER BY 2 — "SELECT ro'yxatidagi ikkinchi ustun bo'yicha". Biz ishga tushirdik (PG 17.6):

sql
SELECT id, matn FROM vazifalar ORDER BY 2 LIMIT 2;

Natija:

text
 id |                   matn                   
----+------------------------------------------
 25 | Algoritmlar: 5 ta masala #o'qish
  8 | Bozordan kartoshka va piyoz olish #bozor
(2 rows)

psql'da tez yozish uchun qulay. Ilova kodida esa nom yozing: kimdir SELECT ga ustun qo'shsa, 2 jim boshqa ustunga ishora qilib qoladi.

Tekshirib ko'ring: ORDER BY bajarildi DESC, id — birinchi qatorlarda qaysi vazifalar bo'ladi?

Javob

Bajarilganlar (true), ular ichida id ning o'sish tartibida. boolean da false < true, kamayishda esa true birinchi. DESC faqat bajarildi ga tegishli, id o'sishda qoladi.

3. NULL qayerda turadi

3.1 Sukut qoidasi

NULL — "qiymat yo'q" (NULL mantiqi darsida chuqur). Tartiblashda PostgreSQL uni eng katta qiymatdek ko'radi. Holat 15 da NULL li ustun yo'q, shuning uchun kanon (PostgreSQL 18.6) kichik VALUES jadvali bilan sinadi — muddat (son) ustuni, biri bo'sh:

sql
SELECT * FROM (VALUES ('a', 3), ('b', NULL), ('c', 1))
  AS t (nom, muddat)
ORDER BY muddat;

SELECT * FROM (VALUES ('a', 3), ('b', NULL), ('c', 1))
  AS t (nom, muddat)
ORDER BY muddat DESC;

Natija:

text
 nom | muddat 
-----+--------
 c   |      1
 a   |      3
 b   |       
(3 rows)

 nom | muddat 
-----+--------
 b   |       
 a   |      3
 c   |      1
(3 rows)

O'sishda NULL oxirida, kamayishda — boshida. ("Eng katta" bo'lgani uchun.) (VALUES …) AS t (nom, muddat) — INSERT va RETURNING darsidagi kabi, vaqtinchalik jadval.

3.2 NULLS FIRST va NULLS LAST

Ko'pincha bu sukut noqulay. Masalan, ALTER TABLE darsida vazifalarga muddat qo'shamiz. "Muddati eng uzoqlari birinchi" deb DESC qilsangiz, muddatsiz vazifalar tepaga chiqib qoladi. Kanon (PostgreSQL 18.6):

sql
SELECT * FROM (VALUES ('a', 3), ('b', NULL), ('c', 1))
  AS t (nom, muddat)
ORDER BY muddat DESC NULLS LAST;

Natija:

text
 nom | muddat 
-----+--------
 a   |      3
 c   |      1
 b   |       
(3 rows)

NULLS LAST — bo'shlar oxirida, NULLS FIRST — boshida. Har ustun uchun alohida yoziladi.

Maslahat: MySQL'da NULL aksincha — eng kichik qiymat (o'sishda boshida), NULLS LAST sintaksisi ham yo'q. Ilovani bir bazadan boshqasiga ko'chirsangiz, saralash jim o'zgarishi mumkin. PostgreSQL'da aniq yozib qo'yish — eng xavfsiz yo'l.

4. LIMIT, OFFSET va sahifalash

4.1 LIMIT va OFFSET

  • LIMIT n — ko'pi bilan n qator.
  • OFFSET m — boshidan m qatorni o'tkazib yubor.

Sahifalash formulasi: LIMIT o'lcham OFFSET (sahifa − 1) × o'lcham. 2-sahifa, 5 tadan — OFFSET 5. Kanon (PostgreSQL 18.6), eng yangilari birinchi:

sql
SELECT id, matn FROM vazifalar
ORDER BY yaratilgan_vaqt DESC, id DESC
LIMIT 5 OFFSET 5;

Natija:

text
 id |                   matn                   
----+------------------------------------------
 35 | Futbol: payshanba 20:00 #sport
 34 | SQL JOIN mashqlarini yechish #o'qish
 33 | Noutbukka SSD qo'yish #ta'mir
 32 | Soliq hisobotini topshirish #ish #to'lov
 31 | Python laboratoriya ishi #o'qish
(5 rows)

1-sahifada 40…36 bor edi, 2-sahifa 35 dan boshlanadi. (Namuna ma'lumotda id'lar vaqt tartibida berilgan — INSERT va RETURNING, shuning uchun ular kamayib boradi.)

Oxirgi sahifa to'liq bo'lmasligi mumkin. Biz ishga tushirdik (PG 17.6):

sql
SELECT id FROM vazifalar ORDER BY id LIMIT 5 OFFSET 38;

Natija:

text
 id 
----
 39
 40
(2 rows)

5 ta so'radik, 2 tasi qoldi — xato emas. OFFSET jadvaldagidan ko'p bo'lsa — (0 rows). API buni "keyingi sahifa yo'q" deb tushunadi.

4.2 FETCH FIRST — standart shakl

LIMIT PostgreSQL, MySQL va SQLite'da bor, lekin SQL standartida yo'q. Standart shakl uzunroq. Biz ishga tushirdik (PG 17.6) — yuqoridagi 2-sahifaning aynan o'zi:

sql
SELECT id, matn FROM vazifalar
ORDER BY yaratilgan_vaqt DESC, id DESC
OFFSET 5 ROWS FETCH FIRST 5 ROWS ONLY;
text
 id |                   matn
----+------------------------------------------
 35 | Futbol: payshanba 20:00 #sport
 34 | SQL JOIN mashqlarini yechish #o'qish
 33 | Noutbukka SSD qo'yish #ta'mir
 32 | Soliq hisobotini topshirish #ish #to'lov
 31 | Python laboratoriya ishi #o'qish
(5 rows)

Natija LIMIT 5 OFFSET 5 bilan aynan bir xil. SQL Server va Oracle'da aynan shu shakl ishlaydi. PostgreSQL'da ikkalasi ham bor — ma'nosi bir xil.

4.3 WITH TIES — chegaradagi tenglar ham

FETCH FIRST ning LIMIT da yo'q bitta imkoniyati bor: WITH TIES. "Top-2 ni ber, lekin 2-o'rindagiga teng bo'lganlarni ham qo'sh". Biz ishga tushirdik (PG 17.6) — eng ko'p vazifasi bor foydalanuvchilar. GROUP BY va count(*) ni Agregatlar, GROUP BY va HAVING darsida o'rganamiz, hozir faqat natijaga qarang: har egasi_id uchun vazifalar soni.

sql
SELECT egasi_id, count(*) AS soni FROM vazifalar
GROUP BY egasi_id
ORDER BY soni DESC
FETCH FIRST 2 ROWS WITH TIES;

SELECT egasi_id, count(*) AS soni FROM vazifalar
GROUP BY egasi_id
ORDER BY soni DESC
LIMIT 2;

Natija:

text
 egasi_id | soni 
----------+------
        1 |    9
        5 |    6
        3 |    6
        2 |    6
(4 rows)

 egasi_id | soni 
----------+------
        1 |    9
        5 |    6
(2 rows)

Uch kishida 6 tadan vazifa bor. LIMIT 2 ulardan birini tanladi — 5 ni. Nega 5, nega 2 yoki 3 emas? Hech qanday sabab yo'q. Tartib faqat soni bo'yicha berilgan, teng soni lar orasida baza o'zi xohlaganini oldi. Boshqa kompyuterda yoki ertaga 2 chiqishi mumkin. WITH TIES esa adolatli: uchala tengni ham berdi.

WITH TIES ORDER BY siz ishlamaydi. Biz ishga tushirdik (PG 17.6):

sql
SELECT id FROM vazifalar FETCH FIRST 2 ROWS WITH TIES;
text
ERROR:  WITH TIES cannot be specified without ORDER BY clause

Mantiqan to'g'ri: tartib bo'lmasa, "teng" ham yo'q.

Tekshirib ko'ring: 100 qatorli jadvalda ORDER BY id LIMIT 10 OFFSET 95 nechta qator qaytaradi? OFFSET 100 chi?

Javob

5 ta (96–100) va 0 ta. OFFSET o'tkazib yuboradi, LIMIT — "ko'pi bilan". Ikkalasi ham xato bermaydi.

5. Barqaror tartib

5.1 Muammo

WITH TIES misolida asosiy tuzoqni ko'rdik: tenglar orasidagi tartib kafolatlanmagan. Sahifalashda bu jiddiy xato beradi. Kanon (PostgreSQL 18.6):

sql
SELECT id, bajarildi FROM vazifalar
ORDER BY bajarildi LIMIT 3;

SELECT id, bajarildi FROM vazifalar
ORDER BY bajarildi, id LIMIT 3;

Natija:

text
 id | bajarildi 
----+-----------
  1 | f
  6 | f
  7 | f
(3 rows)

 id | bajarildi 
----+-----------
  1 | f
  6 | f
  7 | f
(3 rows)

Ikkalasi bir xil chiqdi. Halol aytamiz: kichik jadvalda baza ko'pincha qatorlarni diskdagi tartibda o'qiydi va natija "tasodifan" bir xil bo'ladi. Lekin birinchi so'rovda 20 ta false qator bor va ulardan qaysi 3 tasi chiqishi kafolatlanmagan. Jadval kattalashsa, qatorlar yangilansa yoki baza parallel o'qishni tanlasa, javob o'zgaradi.

Sahifalashda bu nima degani? 1-sahifada id 7 chiqdi. 2-sahifa so'rovida baza teng qatorlarni boshqa tartibda oldi — 7 yana chiqadi, 12 esa hech qaysi sahifada ko'rinmaydi. Foydalanuvchi "vazifam yo'qolib qoldi" deb shikoyat qiladi.

5.2 Yechim: noyob ustun bilan tugatish

Qoida: sahifalanadigan har ORDER BY noyob ustun bilan tugasin. Bizda — id. Shunda ikkita qator hech qachon "teng" bo'lmaydi va tartib to'liq aniqlanadi. Shuning uchun yuqoridagi sahifalash misolida ORDER BY yaratilgan_vaqt DESC, id DESC yozdik: bir xil vaqtda yaratilgan ikki vazifa bo'lsa ham tartib aniq.

flowchart TD
  A["ORDER BY bajarildi"] --> B{"Teng qiymatlar bormi?"}
  B -->|yo'q| C["Tartib aniq"]
  B -->|bor| D["Tenglar tartibi tasodifiy"]
  D --> E["Sahifada takror yoki yo'qolish"]
  A2["ORDER BY bajarildi, id"] --> C

Diagrammadagi "Teng qiymatlar bormi? → bor → tasodifiy → takror yoki yo'qolish" — xato yo'li. id bilan tugagan variant esa savolni chetlab, to'g'ri "Tartib aniq" ga boradi: id noyob, teng qator bo'lmaydi.

6. Katta OFFSET narxi

6.1 OFFSET o'tkazib yuborganini ham o'qiydi

OFFSET 1000000 — "million qatorni o'tkazib yubor". Baza ularni sakrab o'ta olmaydi: avval million qatorni o'qib, sanab, keyin tashlaydi. Sahifa qanchalik chuqur bo'lsa, so'rov shunchalik sekin.

Kanon buni katta to'plamda o'lchagan: 2 mln vazifa (A bosqich katta bazasi, sxema 001–012), PostgreSQL 18.6, Windows 11 + Docker (WSL2), EXPLAIN ANALYZE bilan bitta o'lchov. Ikkala so'rov ham bir xil 20 qatorni oladi:

20 qatorlik sahifa: chuqur OFFSET va keyset
  • OFFSET 1 000 000million qator o'qib tashlandi349,8 ms
  • WHERE id > 1 000 000indeksdan to'g'ri o'sha joyga0,2 ms

Manba: Kanon o'lchovi: PostgreSQL 18.6, 2 mln qatorli vazifalar, EXPLAIN ANALYZE Execution Time (349.837 va 0.213 ms), 2026-10-24

Ustunlar farqiga qarang: ~1600 barobar. Ikkinchi usul — keyset pagination: "oxirgi ko'rgan id dan keyingi 20 tasi" (WHERE id > oxirgi ORDER BY id LIMIT 20). U indeks bo'yicha to'g'ri kerakli joyga boradi. Uni Keyset pagination va katta OFFSET darsida to'liq quramiz.

6.2 OFFSET va o'zgarayotgan ro'yxat

Ikkinchi muammo — sahifalar orasida yangi qator qo'shilsa. Kanon (o'sha katta baza): 1-sahifada {1996536,1990759,1986955}. Shu orada yangi vazifa qo'shildi va u ro'yxat boshiga tushdi. 2-sahifa (OFFSET 3): {1986955,1985233,1978229} — 1986955 ikkinchi marta chiqdi. Hamma qator bittaga pastga surildi.

Shuning uchun Telegram, Instagram kabi "cheksiz lenta"lar OFFSET emas, keyset ishlatadi. Kichik admin jadvallari va "5-sahifaga o'tish" tugmasi bor joylarda esa OFFSET qulay va yetarli.

Tekshirib ko'ring: Ilovada "Keyingi" va "Oldingi" tugmali, 30 qatorli ro'yxat. OFFSET yetarlimi?

Javob

Ha. 30 qatorda OFFSET narxi sezilmaydi, takror xavfi ham kichik. Muammolar katta jadval va tez o'zgaradigan lentada boshlanadi. Har holda ORDER BY noyob ustun bilan tugasin.

7. O'zbek alifbosi bo'yicha saralash

7.1 Muammo

Matn qanday saralanishini collation (taqqoslash qoidasi) belgilaydi: qaysi harf qaysidan oldin, katta-kichik harf qanday ko'riladi. Kanon bazasi en_US.utf8 bilan yaratilgan. U o'zbek alifbosini bilmaydi: O', G', Sh, Ch ni ikki alohida belgi deb ko'radi. Kanon (PostgreSQL 18.6):

sql
SELECT ism FROM (VALUES ('Shahnoza'), ('Sardor'), ('O''tkir'),
  ('Oybek'), ('Zafar'), ('G''ayrat'), ('Gulnora'),
  ('Chori'), ('Bobur')) AS t (ism)
ORDER BY ism;

Natija:

text
   ism    
----------
 Bobur
 Chori
 G'ayrat
 Gulnora
 O'tkir
 Oybek
 Sardor
 Shahnoza
 Zafar
(9 rows)

O'zbek alifbosida lotin harflari (A dan Z gacha) birinchi keladi. Ulardan keyin O', G', Sh, Ch, Ng turadi. Ya'ni O'tkir, G'ayrat, Shahnoza, Chori — Zafar dan keyin turishi kerak. ORDER BY ism COLLATE "C" (baytlar bo'yicha) ham kanonda aynan shu natijani berdi.

7.2 Yechim: ICU collation

PostgreSQL ICU kutubxonasi orqali yuzlab til qoidalarini biladi. Kanon image'ida 7 ta o'zbek collation'i bor (uz-x-icu, uz-Latn-x-icu, uz-Cyrl-x-icu va boshqalar). Kanon (PostgreSQL 18.6):

sql
SELECT ism FROM (VALUES ('Shahnoza'), ('Sardor'), ('O''tkir'),
  ('Oybek'), ('Zafar'), ('G''ayrat'), ('Gulnora'),
  ('Chori'), ('Bobur')) AS t (ism)
ORDER BY ism COLLATE "uz-x-icu";

Natija:

text
   ism    
----------
 Bobur
 Gulnora
 Oybek
 Sardor
 Zafar
 O'tkir
 G'ayrat
 Shahnoza
 Chori
(9 rows)

Endi haqiqiy o'zbek alifbosi: … Sardor, Zafar, O'tkir, G'ayrat, Shahnoza, Chori. Mashinadagi PostgreSQL 17.6 (Windows) da ham uz-x-icu bor — biz sinab ko'rdik, ishlaydi.

COLLATE ni har so'rovda yozish o'rniga ustunning o'ziga berish mumkin: ism text COLLATE "uz-x-icu". Lekin bu indekslar va tezlikka ta'sir qiladi, ICU versiyasi yangilanganda indeksni qayta qurish kerak bo'lishi mumkin. Bizning kanon ustunlarni o'zgartirmagan — o'zbekcha tartib kerak bo'lgan so'rovda COLLATE yoziladi.

Diqqat: Apostrof turi ham muhim. Kanon matnlarida oddiy ' ishlatiladi. Foydalanuvchi ʻ (U+02BB) yoki ’ yozsa, ular boshqa belgilar va saralash/qidiruv boshqacha bo'ladi. Ilovada matnni saqlashdan oldin bir xil apostrofga keltirish foydali.

8. SQL qadami: ro'yxat so'rovi (holat 15, commit yo'q)

Sxema o'zgarmaydi. 25-qism dagi GET /vazifalar?sahifa=2&hajm=5 ro'yxati SQL'da aynan bu darsning so'rovi:

sql
SELECT id, matn, bajarildi, yaratilgan_vaqt
FROM vazifalar
WHERE egasi_id = 1
ORDER BY yaratilgan_vaqt DESC, id DESC
LIMIT 5 OFFSET 5;

LIMIT va OFFSET qiymatlari ilovada parametr bo'lib keladi va server ularni tekshiradi: manfiy emas, hajm 100 dan katta emas. Aks holda bitta so'rov LIMIT 1000000 bilan butun bazani tortib oladi. Repository kodini Parametrli so'rovlar darsida yozamiz. Amaliyot: real loyiha sxemasi darsida esa shu tartib uchun maxsus indeks qo'shamiz — (egasi_id, yaratilgan_vaqt DESC, id DESC).

9. Ko'p uchraydigan xatolar

Xato yoki belgi Sabab Davosi
Tartib har safar boshqacha ORDER BY yo'q Doim ORDER BY
Sahifalarda takror yoki yo'qolgan qator ORDER BY noyob ustun bilan tugamagan Oxiriga , id
Muddatsizlar tepada DESC da NULL boshida NULLS LAST
ORDER BY a, b DESC da a ham kamayadi deb kutilgan DESC faqat oldidagi ustunga Har ustunga alohida
WITH TIES cannot be specified without ORDER BY clause ORDER BY yo'q ORDER BY qo'shing
Chuqur sahifalar sekin Katta OFFSET Keyset pagination
O'tkir Oybek dan oldin en_US/C collation COLLATE "uz-x-icu"

10. Mashqlar

1-mashq (oson): bo'shliqlarni to'ldiring

  • 4-sahifa, har sahifada 10 qator: LIMIT 10 OFFSET
  • O'sish tartibida NULL sukut bo'yicha qayerda:
  • ORDER BY narx DESC, nom da nom qaysi tartibda:
  • Tenglarni ham qo'shadigan shakl: FETCH FIRST 3 ROWS
Yechim
  • 30 — (4 − 1) × 10.
  • oxirida — PostgreSQL NULL ni eng katta qiymat deb ko'radi.
  • o'sish — DESC faqat narx ga tegishli.
  • WITH TIES — ORDER BY bilan birga.

2-mashq (o'rta): eng yangi foydalanuvchilar

Holat 15 da eng oxirgi ro'yxatdan o'tgan 3 foydalanuvchini chiqaring: id, ism, yaratilgan_vaqt. Tartib barqaror bo'lsin.

Yechim

Yechimni biz ishga tushirdik (PG 17.6):

sql
SELECT id, ism, yaratilgan_vaqt
FROM foydalanuvchilar
ORDER BY yaratilgan_vaqt DESC, id DESC
LIMIT 3;

Natija:

text
 id |        ism         |    yaratilgan_vaqt     
----+--------------------+------------------------
  8 | Shahnoza Ergasheva | 2026-10-12 05:00:00+00
  7 | Bekzod Nazarov     | 2026-10-05 17:15:00+00
  6 | Gulnora Saidova    | 2026-10-01 11:05:00+00
(3 rows)

id DESC hozir natijani o'zgartirmaydi (vaqtlar har xil), lekin ertaga ikki kishi bir soniyada ro'yxatdan o'tsa — tartibni u hal qiladi.

3-mashq (qiyin): sahifa va alifbo

(a) Bajarilmagan vazifalar, eng eskisi birinchi, 5 tadan sahifalangan. 3-sahifani chiqaring: id, matn.

(b) Ismlar: Shoira, Sobir, NULL, Chinor, O'g'iloy, Ozoda, Nodir. Ularni o'zbek alifbosi bo'yicha saralang, ismi yo'q (NULL) oxirida bo'lsin. (VALUES …) AS t (ism) dan foydalaning.

Yechim

Ikkala so'rovni biz ishga tushirdik (PG 17.6):

sql
-- (a)
SELECT id, matn
FROM vazifalar
WHERE NOT bajarildi
ORDER BY yaratilgan_vaqt, id
LIMIT 5 OFFSET 10;

-- (b)
SELECT ism
FROM (VALUES ('Shoira'), ('Sobir'), (NULL), ('Chinor'),
             ('O''g''iloy'), ('Ozoda'), ('Nodir')) AS t (ism)
ORDER BY ism COLLATE "uz-x-icu" NULLS LAST;

Natija:

text
 id |                      matn                       
----+-------------------------------------------------
 26 | Dugonamning tug'ilgan kuniga sovg'a #oila
 27 | Yangi xodimga kirish huquqi berish #ish #server
 30 | Instagram uchun surat olish #ish
 31 | Python laboratoriya ishi #o'qish
 32 | Soliq hisobotini topshirish #ish #to'lov
(5 rows)

   ism    
----------
 Nodir
 Ozoda
 Sobir
 O'g'iloy
 Shoira
 Chinor
 
(7 rows)

(a): WHERE avval 20 ta bajarilmaganni qoldiradi, OFFSET 10 ulardan birinchi 10 tasini o'tkazadi. (b): O'g'iloy Sobir dan keyin, Shoira dan oldin — chunki O' alifboda S dan keyin, Sh esa O' dan keyin. Oxirgi bo'sh qator — NULL. NULLS LAST — sukut, lekin aniq yozilgani yaxshi.

11. Real ishda

  • Har ro'yxat API'si — ?sort=-yaratilgan&sahifa=2 kabi parametrlar ORDER BY … LIMIT … OFFSET ga aylanadi. Saralash ustuni foydalanuvchidan kelsa, uni ruxsat etilgan ro'yxat bilan tekshirasiz — ustun nomini parametr qilib bo'lmaydi (Parametrli so'rovlar).
  • Cheksiz lenta — Telegram, Instagram, Uzum Market katalogi: keyset pagination, OFFSET emas.
  • Hisobotlar — "Top 10 sotuvchi" — teng natijalarda WITH TIES yoki aniq ikkinchi mezon; aks holda kim 10-o'ringa tushishi tasodif.
  • Lokalizatsiya — o'zbek, rus, turk tillari uchun ICU collation; ilovada Intl.Collator("uz") ning bazadagi hamkori.
  • Intervyu savoli: "ORDER BY'siz LIMIT nima qaytaradi?" — "kafolatlanmagan, tasodifiy qatorlar".

Xulosa

  • Tartib faqat ORDER BY bilan; bir necha ustun — lug'at tartibi, DESC faqat oldidagi ustunga.
  • NULL — eng katta qiymatdek: o'sishda oxirida, kamayishda boshida; NULLS FIRST/LAST bilan boshqaring.
  • Sahifa: LIMIT o'lcham OFFSET (sahifa − 1) × o'lcham; standart shakli OFFSET … FETCH FIRST … ROWS ONLY; WITH TIES — chegaradagi tenglar ham.
  • Barqaror tartib: ORDER BY noyob ustun (id) bilan tugasin, aks holda sahifalarda takror yoki yo'qolish.
  • Katta OFFSET o'tkazganini ham o'qiydi (kanon: 349.8 ms vs keyset 0.2 ms) va o'zgarayotgan ro'yxatda takror beradi.
  • O'zbek alifbosi — COLLATE "uz-x-icu".

Keyingi dars: UPDATE va DELETE xavfsiz — ma'lumotni o'zgartirish va o'chirish: avval SELECT, keyin tranzaksiya ichida sinash, RETURNING, UPDATE … FROM va TRUNCATE.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
SQL ORDER BY, LIMIT va OFFSET: tartiblash, sahifalash va barqaror tartib — IlmHamroh