09 β ORDER BY, LIMIT, DISTINCT¶
β¬ οΈ Oldingi: 08 β WHERE β filtrlash Β· π README Β· Keyingi: 10 β Built-in funksiyalar (matn, son, sana) β‘οΈ
Bu bobda: natijani
ORDER BYbilan saralashni (bir va bir necha ustun bo'yicha, ASC/DESC, NULL qayerga tushishini),LIMITvaOFFSETbilan natijani kesishni ("eng katta N ta" qolipi va sahifalash),DISTINCTbilan takror qiymatlarni olib tashlashni o'rganamiz β va oxirida bularning hammasini bitta query ichida to'g'ri tartibda yozishni mashq qilamiz.
ORDER BY β saralash¶
Muhim haqiqat: SELECT qatorlarni kafolatlangan tartibda qaytarmaydi. Bugun bir tartibda chiqqani, ertaga ham shunday chiqadi degani emas. Tartib kerakmi β uni doim ORDER BY bilan ochiq-oydin aytamiz. Bu xuddi kutubxonachiga "kitoblarni yili bo'yicha terib ber" deb aniq topshiriq berishga o'xshaydi.
SELECT * FROM kitoblar ORDER BY yil; -- o'sish tartibida (ASC β default)
SELECT * FROM kitoblar ORDER BY yil DESC; -- kamayish tartibida
SELECT * FROM kitoblar ORDER BY janr, yil DESC; -- avval janr A-Z, har janr ichida yil yangiβeski
Har xil turdagi ustunlar qanday saralanadi:
| Tur | ASC (default) | DESC |
|---|---|---|
| Son (INT, DECIMAL) | kichik β katta | katta β kichik |
| Matn (VARCHAR) | alifbo: A β Z | Z β A |
| Sana (DATE, DATETIME) | eski β yangi | yangi β eski |
π ORDER BY janr, yil DESC da DESC faqat yilga taalluqli! Ikkalasini ham teskari qilmoqchi bo'lsangiz, har biriga alohida yozasiz: ORDER BY janr DESC, yil DESC.
π‘ NULL ham saralanadi: MySQL'da ASC tartibda NULL'lar eng boshida, DESC'da eng oxirida chiqadi. Sinab ko'ring: SELECT * FROM taksi.safarlar ORDER BY baho; β baho qo'yilmagan safar birinchi chiqadi.
Alias va hisob-kitob natijasi bo'yicha ham saralash mumkin:
SELECT nomi, narx * soni AS ombor_qiymati
FROM dokon.mahsulotlar
ORDER BY ombor_qiymati DESC; -- eng "qimmat zaxira" tepada
β οΈ Sonlarni VARCHAR ustunda saqlasangiz, ular matn sifatida saralanadi: '10' '9'dan oldin keladi (chunki alifboda '1' '9'dan kichik). Sonlar uchun doim son turlarini ishlating (5-bobni eslang).
LIMIT β faqat N ta qator¶
LIMIT natijaning faqat boshidagi N ta qatorini qoldiradi. OFFSET esa "boshidan nechtasini tashlab ket" deydi:
SELECT * FROM kitoblar ORDER BY sahifa DESC LIMIT 3; -- eng qalin 3 ta kitob
SELECT * FROM kitoblar ORDER BY yil LIMIT 5 OFFSET 5; -- 6β10-qatorlar (2-"sahifa")
SELECT * FROM kitoblar ORDER BY yil LIMIT 5, 5; -- xuddi shu: LIMIT offset, soni
π LIMIT 5, 5 qisqa yozuvida birinchi son β OFFSET, ikkinchisi β qatorlar soni. Chalkashtirib yubormaslik uchun LIMIT 5 OFFSET 5 shakli tushunarliroq β biz shuni ishlatamiz.
β οΈ LIMIT'ni ORDER BY'siz yozish β lotereya o'ynash: MySQL qaysi 3 qatorni berishi kafolatlanmagan. "Eng katta", "eng oxirgi", "birinchi" degan so'z bor joyda ORDER BY va LIMIT doim juft yuradi.
TOP-N pattern (yodlab oling): "eng katta/kichik N ta" = ORDER BY ... DESC/ASC LIMIT N.
LIMIT + OFFSET β saytlardagi sahifalash (pagination) asosi. Har sahifada 5 ta mahsulot ko'rsatsak:
| Sahifa | Query oxiri |
|---|---|
| 1-sahifa | LIMIT 5 OFFSET 0 |
| 2-sahifa | LIMIT 5 OFFSET 5 |
| 3-sahifa | LIMIT 5 OFFSET 10 |
Formula oddiy: OFFSET = (sahifa - 1) Γ sahifa_hajmi.
π‘ Qiziq hiyla: ORDER BY RAND() LIMIT 1 β jadvaldan tasodifiy bitta qator. Kichik jadvallarda viktorina savoli tanlash kabi ishlarga qulay (katta jadvallarda sekin ishlaydi).
DISTINCT β takrorlarni olib tashlash¶
7-bobda DISTINCT bilan qisqacha tanishgan edik, endi chuqurroq ko'ramiz. DISTINCT natijadagi takror qatorlarni olib tashlaydi β "qanday qiymatlar bor o'zi?" degan savolga javob beradi:
SELECT janr FROM kitoblar; -- 10 qator: roman, roman, sarguzasht, ...
SELECT DISTINCT janr FROM kitoblar; -- 4 qator: roman, sarguzasht, sheriyat, ertak
Bir nechta ustun yozsangiz, kombinatsiya (juftlik) takrorsiz bo'ladi:
SELECT DISTINCT boshlanish, tugash FROM taksi.safarlar;
-- 10 safar bor, lekin 9 qator chiqadi: "Markaz β Chilonzor" yo'nalishi 2 marta uchragan
π DISTINCT SELECT'dagi hamma ustunlarga birgalikda taalluqli, faqat birinchisiga emas. SELECT DISTINCT janr, yil deganda "janri takrorlanmasin" emas, "janr+yil juftligi takrorlanmasin" deyilyapti.
DISTINCT'ni ORDER BY va LIMIT bilan birga ishlatish mumkin:
SELECT DISTINCT janr FROM kitoblar ORDER BY janr; -- β
takrorsiz va alifbo tartibida
-- SELECT DISTINCT janr FROM kitoblar ORDER BY yil; -- β MySQL 8 xato beradi:
-- DISTINCT bilan faqat SELECT'da BOR ustunlar bo'yicha saralash mumkin
Nega xato? Bir janrga bir nechta yil to'g'ri keladi ("roman" 1869 hammi, 1928 hammi?) β MySQL qaysi yil bo'yicha saralashni bilmaydi.
π‘ "Nechta xil janr bor?" deb sanash uchun COUNT(DISTINCT janr) ishlatiladi β bu bilan 11-bobda tanishamiz.
Hammasi birga β yozish tartibi¶
Bu bobgacha o'rgangan qismlarimiz queryda qat'iy tartibda turadi:
SELECT DISTINCT ustunlar -- 1) nimani olamiz (DISTINCT β ixtiyoriy)
FROM jadval -- 2) qayerdan
WHERE shart -- 3) qaysi qatorlar (filtrlash)
ORDER BY ustun DESC -- 4) qanday tartibda
LIMIT 5 OFFSET 0; -- 5) nechtasini (doim eng oxirida)
Tartibni buzib LIMIT 3 ORDER BY yil yozsangiz β sintaksis xatosi. Hammasi birga ishlagan real misol:
-- Roman janridagi eng yangi 2 ta kitob:
SELECT nomi, yil FROM kitoblar
WHERE janr = 'roman'
ORDER BY yil DESC
LIMIT 2;
-- Natija: Mehrobdan chayon (1928), Otkan kunlar (1925)
9-bob masalalari¶
- (kutubxona) Kitoblarni yil bo'yicha eskiβyangi tartibda chiqaring
- (kutubxona) Kitoblarni qalinligi bo'yicha qalinβyupqa tartibda chiqaring
- (kutubxona) Eng eski 3 ta kitob
- (kutubxona) Eng qalin kitob (1 ta)
- (kutubxona) Eng yupqa kitob (maslahat: 4-masalaning teskarisi)
- (kutubxona) A'zolarni qo'shilgan sanasi bo'yicha yangiβeski tartibda chiqaring
- (kutubxona) Eng oxirgi qo'shilgan 2 ta a'zo
- (kutubxona) Avval janr bo'yicha alifbo, har janr ichida yil bo'yicha yangiβeski
- (kutubxona) Mualliflarni tug'ilgan yili bo'yicha saralang va eng keksa 2 tasini chiqaring
- (dokon) Eng qimmat 3 ta mahsulot
- (dokon) Eng arzon mahsulot
- (dokon) Omborda eng ko'p qolgan 3 ta mahsulot
- (dokon) Mahsulotlar 2-sahifasi: 5 tadan bo'lganda 6β10-mahsulotlar (LIMIT + OFFSET; formulani eslang)
- (dokon) Eng oxirgi 3 ta buyurtma (sana bo'yicha)
- (klinika) Eng tajribali shifokor
- (klinika) Qabul narxi bo'yicha arzonβqimmat shifokorlar; klinikada qanday mutaxassisliklar bor β takrorsiz ro'yxat (DISTINCT) β 2 ta query
- (klinika) Eng katta yoshli bemor (tug'ilgan_sana bo'yicha o'ylang: eng katta yosh = eng KICHIK sana!)
- (taksi) Eng uzun 3 ta safar
- (taksi) Eng qimmat safar; eng yuqori reytingli haydovchi; safarlar qaysi manzillarda tugagan β takrorsiz ro'yxat (DISTINCT) β 3 ta query
- (taksi) Safarlarni sana bo'yicha yangiβeski, bir xil sanada narx bo'yicha qimmatβarzon tartibda chiqaring (maslahat: ikkinchi kalit faqat birinchisi teng bo'lganda ishga tushadi)