β Ertalabki masala: klassik intervyu savoli
Jadval:
Vazifa: har bir bo'limdagi eng yuqori maosh oladigan xodimni chiqaring. Bitta bo'limda bir xil maosh bilan ikki kishi bo'lsa β ikkalasi ham ro'yxatda bo'lsin.
π― Bu savol ish suhbatlarida eng ko'p beriladigan uchlikdan biri. Kamida ikki xil yechimi bor.
βοΈ O'z variantingizni izohda yozing β 20:00 da ikkala yechimni ham tahlil qilamiz π
π― Endi amaliyot: Har bo'limdagi eng yuqori maosh
Masala saytda ham bor β yozing, tizim javobingizni darhol tekshiradi π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Jadval:
employees(id, name, department, salary)Vazifa: har bir bo'limdagi eng yuqori maosh oladigan xodimni chiqaring. Bitta bo'limda bir xil maosh bilan ikki kishi bo'lsa β ikkalasi ham ro'yxatda bo'lsin.
SELECT ???
FROM employees
???
π― Bu savol ish suhbatlarida eng ko'p beriladigan uchlikdan biri. Kamida ikki xil yechimi bor.
βοΈ O'z variantingizni izohda yozing β 20:00 da ikkala yechimni ham tahlil qilamiz π
π― Endi amaliyot: Har bo'limdagi eng yuqori maosh
Masala saytda ham bor β yozing, tizim javobingizni darhol tekshiradi π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
πͺ ROW_NUMBER, RANK, DENSE_RANK β farqi nimada?
Uchalasi ham qatorlarga raqam beradi, lekin teng qiymatlarda boshqacha yo'l tutadi.
Misol: ballar 100, 90, 90, 80
Har qatorga noyob raqam. Teng bo'lsa ham farqlaydi (qaysi biri 2, qaysi biri 3 β tasodifiy, agar
Tenglar bir xil o'rin oladi, keyingi o'rin sakraydi. Sport natijalari shunday.
Tenglar bir xil o'rin oladi, sakrash yo'q.
PARTITION BY β guruh ichida sanash uchun:
Bu Β«har bo'lim ichida maosh bo'yicha tartiblab, 1 dan sanashΒ» degani.
π Qaysi birini tanlash:
β’ dublikat o'chirish, Β«har guruhdan bittasiΒ» β
β’ Β«top 3Β», tenglar ham kirsin β
β’ haqiqiy reyting, o'rin sakrasin β
π― Endi amaliyot: RANK va DENSE_RANK farqi
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Uchalasi ham qatorlarga raqam beradi, lekin teng qiymatlarda boshqacha yo'l tutadi.
Misol: ballar 100, 90, 90, 80
ROW_NUMBER() β 1, 2, 3, 4Har qatorga noyob raqam. Teng bo'lsa ham farqlaydi (qaysi biri 2, qaysi biri 3 β tasodifiy, agar
ORDER BY aniq bo'lmasa).RANK() β 1, 2, 2, 4Tenglar bir xil o'rin oladi, keyingi o'rin sakraydi. Sport natijalari shunday.
DENSE_RANK() β 1, 2, 2, 3Tenglar bir xil o'rin oladi, sakrash yo'q.
SELECT
name,
score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS rn,
RANK() OVER (ORDER BY score DESC) AS rnk,
DENSE_RANK() OVER (ORDER BY score DESC) AS drnk
FROM results;
PARTITION BY β guruh ichida sanash uchun:
ROW_NUMBER() OVER (
PARTITION BY department
ORDER BY salary DESC
)
Bu Β«har bo'lim ichida maosh bo'yicha tartiblab, 1 dan sanashΒ» degani.
π Qaysi birini tanlash:
β’ dublikat o'chirish, Β«har guruhdan bittasiΒ» β
ROW_NUMBERβ’ Β«top 3Β», tenglar ham kirsin β
DENSE_RANKβ’ haqiqiy reyting, o'rin sakrasin β
RANKπ― Endi amaliyot: RANK va DENSE_RANK farqi
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
β
Ertalabki masala yechimi: har bo'limdagi eng yuqori maosh
1-usul: window funksiya (zamonaviy, tavsiya etiladi)
Bu yerda
2-usul: korrelyatsion subquery (eski bazalarda ham ishlaydi)
Qaysi biri yaxshi? Odatda window β jadval bir marta o'qiladi. Subquery esa har qator uchun ichki so'rovni qayta bajarishi mumkin (index bo'lmasa ayniqsa og'ir).
β Eng ko'p uchraydigan xato:
Bu yerda
π¬ Siz qaysi usulni yozgan edingiz?
π― Endi amaliyot: Ikkinchi eng yuqori maosh
Shu mantiqning davomi β intervyu klassikasi π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
1-usul: window funksiya (zamonaviy, tavsiya etiladi)
WITH ranked AS (
SELECT name, department, salary,
RANK() OVER (PARTITION BY department
ORDER BY salary DESC) AS r
FROM employees
)
SELECT name, department, salary
FROM ranked
WHERE r = 1;
Bu yerda
RANK ishlatildi, chunki shartda Β«bir xil maosh bo'lsa ikkalasi hamΒ» deyilgan. ROW_NUMBER bo'lsa faqat bittasi chiqardi.2-usul: korrelyatsion subquery (eski bazalarda ham ishlaydi)
SELECT name, department, salary
FROM employees e
WHERE salary = (
SELECT MAX(salary)
FROM employees
WHERE department = e.department
);
Qaysi biri yaxshi? Odatda window β jadval bir marta o'qiladi. Subquery esa har qator uchun ichki so'rovni qayta bajarishi mumkin (index bo'lmasa ayniqsa og'ir).
β Eng ko'p uchraydigan xato:
SELECT name, department, MAX(salary)
FROM employees
GROUP BY department; -- xato!
Bu yerda
name qaysi xodimniki ekani noma'lum. PostgreSQL xato beradi, MySQL esa tasodifiy ism qaytaradi β bu yanada yomon, chunki so'rov Β«ishlaydiΒ».π¬ Siz qaysi usulni yozgan edingiz?
π― Endi amaliyot: Ikkinchi eng yuqori maosh
Shu mantiqning davomi β intervyu klassikasi π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Ballar: 100, 90, 90, 80. RANK() OVER (ORDER BY score DESC) bo'yicha 80 ballning o'rni nechchi bo'ladi?
Anonymous Quiz
20%
3
60%
4
20%
2
π DISTINCT bilan Β«tuzatishΒ» β eng qimmat odat
So'rov dublikat qaytardi. Ko'pchilik shu zahoti
Muammo:
Avval dublikat borligini tekshiring:
Dublikat qatorlarni o'chirish (eng ishonchli usul β
Bu har bir
β οΈ
π
π― Endi amaliyot: Takrorlangan email larni topish
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
So'rov dublikat qaytardi. Ko'pchilik shu zahoti
DISTINCT qo'shadi va davom etadi.SELECT DISTINCT c.name, o.amount
FROM customers c
JOIN orders o ON o.customer_id = c.id;
Muammo:
DISTINCT sababni emas, alomatni yashiradi. Dublikat paydo bo'lgan bo'lsa, demak JOIN kaliti o'ng jadvalda unikal emas. Va agar ikki mijozning summasi tasodifan teng bo'lsa β DISTINCT ulardan birini o'chirib tashlaydi. Hisobot jimgina noto'g'ri bo'ladi.Avval dublikat borligini tekshiring:
SELECT email, COUNT(*)
FROM users
GROUP BY email
HAVING COUNT(*) > 1;
Dublikat qatorlarni o'chirish (eng ishonchli usul β
ROW_NUMBER):WITH d AS (
SELECT id,
ROW_NUMBER() OVER (PARTITION BY email
ORDER BY created_at) AS rn
FROM users
)
DELETE FROM users
WHERE id IN (SELECT id FROM d WHERE rn > 1);
Bu har bir
email uchun eng eskisini qoldiradi, qolganini o'chiradi.β οΈ
DELETE yozishdan oldin doim shu so'rovni SELECT bilan bir marta ishga tushiring β nima o'chishini ko'ring.π
DISTINCT yozgingiz kelsa, avval bitta savol bering: bu dublikat qayerdan keldi?π― Endi amaliyot: Takrorlangan email larni topish
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
β
Ertalabki test javobi: 4-o'rin
Amalda bu qayerda muhim?
Vazifa: Β«top 3 mahsulotΒ» ro'yxatini chiqaring.
Agar boshliq Β«menga aniq 3 qator kerakΒ» desa β
Bu texnik emas, biznes savoli. Shuning uchun analitik so'rov yozishdan oldin aniqlab oladi.
π¬ Sizning ishingizda Β«top NΒ» qanday hisoblanadi?
π― Endi amaliyot: Takroriy yozuvlarni tozalash
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
RANK() tenglardan keyin o'rinni sakratadi: 1, 2, 2, 4. Uchinchi o'rin umuman bo'lmaydi.DENSE_RANK() esa sakratmaydi: 1, 2, 2, 3.Amalda bu qayerda muhim?
Vazifa: Β«top 3 mahsulotΒ» ro'yxatini chiqaring.
-- DENSE_RANK: teng natijalar ham kiradi
WHERE drnk <= 3 -- 3 ta o'rin, lekin 4-5 qator bo'lishi mumkin
-- ROW_NUMBER: qat'iy 3 qator
WHERE rn <= 3
Agar boshliq Β«menga aniq 3 qator kerakΒ» desa β
ROW_NUMBER. Agar Β«uchinchi o'rinni bo'lishganlar ham chiqsinΒ» desa β DENSE_RANK.Bu texnik emas, biznes savoli. Shuning uchun analitik so'rov yozishdan oldin aniqlab oladi.
π¬ Sizning ishingizda Β«top NΒ» qanday hisoblanadi?
π― Endi amaliyot: Takroriy yozuvlarni tozalash
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
β Ertalabki masala: ketma-ket kunlar
Jadval:
Vazifa: kamida 3 kun ketma-ket tizimga kirgan foydalanuvchilarni toping.
Masalan:
β’ user 1 β 5, 6, 7-oktabr β
β’ user 2 β 5, 6, 8-oktabr β
β οΈ Ogohlantirish: bu masala
π― Bu Β«gaps and islandsΒ» deb ataladigan klassik masala. Uni bilgan odam intervyuda darrov ajralib turadi.
βοΈ Fikringizni izohda yozing, 13:00 da to'liq tahlil qilamiz π
π― Endi amaliyot: 3+ ketma-ket kun kirgan foydalanuvchilar
Masala saytda tayyor turibdi β urinib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Jadval:
logins(user_id, login_date) β har bir kirish bitta qator.Vazifa: kamida 3 kun ketma-ket tizimga kirgan foydalanuvchilarni toping.
Masalan:
β’ user 1 β 5, 6, 7-oktabr β
β’ user 2 β 5, 6, 8-oktabr β
SELECT user_id
FROM logins
???
β οΈ Ogohlantirish: bu masala
GROUP BY bilan yechilmaydi. Bu yerda boshqa usul kerak.π― Bu Β«gaps and islandsΒ» deb ataladigan klassik masala. Uni bilgan odam intervyuda darrov ajralib turadi.
βοΈ Fikringizni izohda yozing, 13:00 da to'liq tahlil qilamiz π
π― Endi amaliyot: 3+ ketma-ket kun kirgan foydalanuvchilar
Masala saytda tayyor turibdi β urinib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
π Gaps and islands: ketma-ketlikni qanday topish kerak
Ertalabki masalaning yechimi. Butun sir bitta hiylada.
Hiyla: agar sanalar ketma-ket bo'lsa, ularning tartib raqami ham ketma-ket o'sadi. Demak
Nima bo'lyapti?
5, 6, 7-oktabr β raqamlari 1, 2, 3 β ayirma har uchalasida bir xil β bitta guruh, 3 qator β shart bajarildi.
5, 6, 8-oktabr β 8 da ayirma o'zgaradi β yangi guruh boshlanadi β hech qaysi guruhda 3 ta yo'q.
β οΈ
π Xuddi shu usul boshqa joylarda ham ishlaydi:
β’ streak hisoblash (ketma-ket kunlar)
β’ uzluksiz ishlagan davrlar
β’ sensor ma'lumotlaridagi uzilishlar
β’ abonement to'lovlaridagi bo'shliqlar
π¬ Bu usulni bilarmidingiz? Boshqa yechim taklif qila olasizmi?
π― Endi amaliyot: Eng uzun g'alabalar seriyasi
Xuddi shu usul bilan yechiladi β mustahkamlab oling π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Ertalabki masalaning yechimi. Butun sir bitta hiylada.
Hiyla: agar sanalar ketma-ket bo'lsa, ularning tartib raqami ham ketma-ket o'sadi. Demak
sana β tartib_raqami ayirmasi bitta Β«orolchaΒ» ichida o'zgarmaydi.WITH t AS (
SELECT user_id, login_date,
login_date - (ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY login_date
) * INTERVAL '1 day') AS grp
FROM (SELECT DISTINCT user_id, login_date FROM logins) x
)
SELECT user_id
FROM t
GROUP BY user_id, grp
HAVING COUNT(*) >= 3;
Nima bo'lyapti?
5, 6, 7-oktabr β raqamlari 1, 2, 3 β ayirma har uchalasida bir xil β bitta guruh, 3 qator β shart bajarildi.
5, 6, 8-oktabr β 8 da ayirma o'zgaradi β yangi guruh boshlanadi β hech qaysi guruhda 3 ta yo'q.
β οΈ
SELECT DISTINCT shart: bitta kunda ikki marta kirgan bo'lsa, raqamlar siljib ketadi va natija buziladi.π Xuddi shu usul boshqa joylarda ham ishlaydi:
β’ streak hisoblash (ketma-ket kunlar)
β’ uzluksiz ishlagan davrlar
β’ sensor ma'lumotlaridagi uzilishlar
β’ abonement to'lovlaridagi bo'shliqlar
π¬ Bu usulni bilarmidingiz? Boshqa yechim taklif qila olasizmi?
π― Endi amaliyot: Eng uzun g'alabalar seriyasi
Xuddi shu usul bilan yechiladi β mustahkamlab oling π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
π1
π― SQL ni o'qib emas, yozib o'rganasiz
Bugungi Β«gaps and islandsΒ» masalasini o'qib chiqdingiz. Tushundingiz. Endi rostini aytaylik: bir haftadan keyin uni o'zingiz noldan yoza olasizmi?
Ko'pchilik yoza olmaydi. Chunki o'qish β tanish tuyg'usi beradi, ko'nikma bermaydi. Ko'nikma faqat bo'sh oynaga so'rov yozib, xato olib, tuzatib paydo bo'ladi.
Shuning uchun sqlmaster.uz qurildi:
πΉ 195 ta masala β SELECT asoslaridan window funksiya va CTE gacha
πΉ Real schemalar β Uzum, Click, taksi, bank jadvallari. O'quv misollari emas, ishdagi vaziyatlar
πΉ Yozasiz β tizim darrov tekshiradi. To'g'ri javobni emas, sizning so'rovingiz natijasini solishtiradi
πΉ Muhokama bo'limi β boshqalarning yechimini ko'rasiz. Bitta masalaning 5 xil yechimi bo'ladi
πΉ Bosqichma-bosqich β Oson β O'rtacha β Qiyin
π‘ Birinchi 50 ta masala mutlaqo bepul. Ro'yxatdan o'tish 30 soniya, karta kerak emas.
Bugun 3 ta masala yeching. Ertaga yana 3 ta. Bir oydan keyin intervyuda Β«JOIN yozib beringΒ» degan gap sizni cho'chitmaydi.
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Bugungi Β«gaps and islandsΒ» masalasini o'qib chiqdingiz. Tushundingiz. Endi rostini aytaylik: bir haftadan keyin uni o'zingiz noldan yoza olasizmi?
Ko'pchilik yoza olmaydi. Chunki o'qish β tanish tuyg'usi beradi, ko'nikma bermaydi. Ko'nikma faqat bo'sh oynaga so'rov yozib, xato olib, tuzatib paydo bo'ladi.
Shuning uchun sqlmaster.uz qurildi:
πΉ 195 ta masala β SELECT asoslaridan window funksiya va CTE gacha
πΉ Real schemalar β Uzum, Click, taksi, bank jadvallari. O'quv misollari emas, ishdagi vaziyatlar
πΉ Yozasiz β tizim darrov tekshiradi. To'g'ri javobni emas, sizning so'rovingiz natijasini solishtiradi
πΉ Muhokama bo'limi β boshqalarning yechimini ko'rasiz. Bitta masalaning 5 xil yechimi bo'ladi
πΉ Bosqichma-bosqich β Oson β O'rtacha β Qiyin
π‘ Birinchi 50 ta masala mutlaqo bepul. Ro'yxatdan o'tish 30 soniya, karta kerak emas.
Bugun 3 ta masala yeching. Ertaga yana 3 ta. Bir oydan keyin intervyuda Β«JOIN yozib beringΒ» degan gap sizni cho'chitmaydi.
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
β Ertalabki savol: qaysi biri tezroq?
Ikkala so'rov ham bir xil natija beradi β buyurtma bergan mijozlar ro'yxati.
Sizningcha qaysi biri tezroq ishlaydi?
A)
B)
C) Farqi yo'q
βοΈ Javobingizni izohda yozing. Kechqurun 20:00 da query plan bilan ko'rsataman π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Ikkala so'rov ham bir xil natija beradi β buyurtma bergan mijozlar ro'yxati.
-- 1-variant
SELECT * FROM customers c
WHERE c.id IN (SELECT customer_id FROM orders);
-- 2-variant
SELECT * FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.id
);
Sizningcha qaysi biri tezroq ishlaydi?
A)
IN tezroqB)
EXISTS tezroqC) Farqi yo'q
βοΈ Javobingizni izohda yozing. Kechqurun 20:00 da query plan bilan ko'rsataman π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
π Index bor, lekin so'rov sekin. Nega?
Index yaratilgan bo'lsa ham, baza uni ishlatmasligi mumkin. Mana eng ko'p uchraydigan 5 holat:
1οΈβ£ Ustunga funksiya qo'llansa
Index
2οΈβ£ LIKE boshida foiz bo'lsa
3οΈβ£ Tip mos kelmasa
4οΈβ£ OR ishlatilsa
5οΈβ£ Jadval kichik bo'lsa
1000 qatorli jadvalda to'liq o'qish indexdan tez. Bu xato emas β optimizator to'g'ri qaror qilyapti.
π Taxmin qilmang, tekshiring:
Natijada
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Index yaratilgan bo'lsa ham, baza uni ishlatmasligi mumkin. Mana eng ko'p uchraydigan 5 holat:
1οΈβ£ Ustunga funksiya qo'llansa
WHERE DATE(created_at) = '2026-10-06' -- index ishlamaydi
WHERE created_at >= '2026-10-06'
AND created_at < '2026-10-07' -- index ishlaydi
Index
created_at qiymatlarini saqlaydi, DATE(created_at) natijasini emas.2οΈβ£ LIKE boshida foiz bo'lsa
LIKE 'Ali%' β ishlaydiLIKE '%Ali' β ishlamaydi (index alifbo tartibida, boshi noma'lum)3οΈβ£ Tip mos kelmasa
WHERE phone = 998901234567 β phone matn ustuni bo'lsa, baza har qatorni songa aylantiradi va index chetda qoladi. Tirnoq qo'ying.4οΈβ£ OR ishlatilsa
WHERE a = 1 OR b = 2 β ko'pincha to'liq skan. UNION ALL bilan ikki so'rovga bo'lish tezroq bo'lishi mumkin.5οΈβ£ Jadval kichik bo'lsa
1000 qatorli jadvalda to'liq o'qish indexdan tez. Bu xato emas β optimizator to'g'ri qaror qilyapti.
π Taxmin qilmang, tekshiring:
EXPLAIN ANALYZE
SELECT ...;
Natijada
Seq Scan ko'rsangiz β index ishlamayapti. Index Scan yoki Bitmap Index Scan ko'rsangiz β ishlayapti.ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
β
Javob: C β zamonaviy bazalarda farqi deyarli yo'q
PostgreSQL va SQL Server optimizatori
Lekin ikkita muhim farq bor π
1οΈβ£ NULL bilan xulq-atvor.
2οΈβ£ Ichki ro'yxat katta bo'lsa.
Uchinchi variant β JOIN:
β οΈ Bu yerda
π Xulosa: Β«bor-yo'qliginiΒ» tekshirish uchun β
π¬
π― Endi amaliyot: EXISTS va IN β qayta yozish
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
PostgreSQL va SQL Server optimizatori
IN va EXISTS ni ko'pincha bir xil planga aylantiradi (semi-join). Ya'ni Β«EXISTS doim tezroqΒ» degan eski maslahat bugun har doim ham to'g'ri emas.Lekin ikkita muhim farq bor π
1οΈβ£ NULL bilan xulq-atvor.
NOT IN ichida bitta NULL bo'lsa, natija butunlay bo'sh chiqadi. NOT EXISTS da bunday muammo yo'q. Shuning uchun inkorda doim NOT EXISTS.2οΈβ£ Ichki ro'yxat katta bo'lsa.
IN (1, 2, 3, ... 10000) ko'rinishidagi qo'lda yozilgan uzun ro'yxat sekin ishlaydi β vaqtinchalik jadval yoki JOIN afzal.Uchinchi variant β JOIN:
SELECT DISTINCT c.*
FROM customers c
JOIN orders o ON o.customer_id = c.id;
β οΈ Bu yerda
DISTINCT kerak bo'ldi, chunki mijozning 5 ta buyurtmasi bo'lsa 5 marta chiqadi. EXISTS da bu muammo yo'q β u Β«bormi?Β» degan savolga javob beradi, ko'paytirmaydi.π Xulosa: Β«bor-yo'qliginiΒ» tekshirish uchun β
EXISTS. Ustun kerak bo'lsa β JOIN.π¬
EXPLAIN ANALYZE ni ishlatib ko'rganmisiz?π― Endi amaliyot: EXISTS va IN β qayta yozish
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
β Ertalabki masala: oylik o'sish
Jadval:
Vazifa: har oy uchun umumiy savdo va o'tgan oyga nisbatan o'sish foizini chiqaring.
Natija shunday ko'rinishi kerak:
π― Bu hisobot har bir analitikdan haftada bir marta so'raladi. Ikki bosqichda yechiladi: avval oy bo'yicha guruhlash, keyin o'tgan qatorga murojaat.
βοΈ Qaysi funksiya kerakligini bilasizmi? Izohda yozing, kechqurun yechamiz π
π― Endi amaliyot: Oylik o'sish foizi
Masala saytda ham bor β yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Jadval:
sales(sale_date, amount)Vazifa: har oy uchun umumiy savdo va o'tgan oyga nisbatan o'sish foizini chiqaring.
Natija shunday ko'rinishi kerak:
oy jami o'sish_%
2026-08 120 000 β
2026-09 150 000 +25.0
2026-10 135 000 -10.0
π― Bu hisobot har bir analitikdan haftada bir marta so'raladi. Ikki bosqichda yechiladi: avval oy bo'yicha guruhlash, keyin o'tgan qatorga murojaat.
βοΈ Qaysi funksiya kerakligini bilasizmi? Izohda yozing, kechqurun yechamiz π
π― Endi amaliyot: Oylik o'sish foizi
Masala saytda ham bor β yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
π
Sanalar bilan ishlashda 3 ta tuzoq
1οΈβ£ BETWEEN va timestamp
31-yanvar soat 10:00 da yaratilgan yozuv chiqmaydi. Chunki
β To'g'ri usul β yarim ochiq oraliq:
Bu ham to'g'ri, ham indexni ishlatadi.
2οΈβ£ Oy bo'yicha guruhlash
3οΈβ£ Vaqt zonasi
Server UTC da, siz Toshkentdasiz. Yarim tundan keyingi buyurtma Β«kechagi kunΒ» bo'lib hisoblanishi mumkin. Kunlik hisobot 5 soatga siljiydi:
π Kunlik hisobotdagi raqam boshqa tizimdagi raqamga to'g'ri kelmayotgan bo'lsa β birinchi navbatda shu uchtasini tekshiring.
π― Endi amaliyot: Oy kesimida daromad
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
1οΈβ£ BETWEEN va timestamp
WHERE created_at BETWEEN '2026-01-01' AND '2026-01-31'
31-yanvar soat 10:00 da yaratilgan yozuv chiqmaydi. Chunki
'2026-01-31' aslida 2026-01-31 00:00:00 degani. Butun bir kun yo'qoladi.β To'g'ri usul β yarim ochiq oraliq:
WHERE created_at >= '2026-01-01'
AND created_at < '2026-02-01'
Bu ham to'g'ri, ham indexni ishlatadi.
2οΈβ£ Oy bo'yicha guruhlash
-- PostgreSQL
SELECT DATE_TRUNC('month', sale_date) AS oy, SUM(amount)
FROM sales GROUP BY 1 ORDER BY 1;
-- MySQL
SELECT DATE_FORMAT(sale_date, '%Y-%m') AS oy, SUM(amount)
FROM sales GROUP BY 1 ORDER BY 1;
3οΈβ£ Vaqt zonasi
Server UTC da, siz Toshkentdasiz. Yarim tundan keyingi buyurtma Β«kechagi kunΒ» bo'lib hisoblanishi mumkin. Kunlik hisobot 5 soatga siljiydi:
SELECT DATE_TRUNC('day',
created_at AT TIME ZONE 'Asia/Tashkent') AS kun
FROM orders GROUP BY 1;π Kunlik hisobotdagi raqam boshqa tizimdagi raqamga to'g'ri kelmayotgan bo'lsa β birinchi navbatda shu uchtasini tekshiring.
π― Endi amaliyot: Oy kesimida daromad
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
β
Yechim: oylik o'sish foizi β LAG bilan
Uchta muhim nuqta:
πΉ
πΉ
πΉ
π‘ Birinchi oyda
πΉ Window funksiyalar bo'yicha saytda 37 ta masala bor β
π¬
π― Endi amaliyot: Payme: oylik o'sish
Real keys β o'sha LAG bilan yechiladi π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
WITH oylik AS (
SELECT DATE_TRUNC('month', sale_date) AS oy,
SUM(amount) AS jami
FROM sales
GROUP BY 1
)
SELECT
oy,
jami,
LAG(jami) OVER (ORDER BY oy) AS otgan_oy,
ROUND(
100.0 * (jami - LAG(jami) OVER (ORDER BY oy))
/ NULLIF(LAG(jami) OVER (ORDER BY oy), 0),
1) AS osish_foiz
FROM oylik
ORDER BY oy;
Uchta muhim nuqta:
πΉ
LAG(jami) β oldingi qatordagi qiymatni oladi. Aksincha keyingisi kerak bo'lsa β LEAD.πΉ
NULLIF(x, 0) β nolga bo'lishdan himoya. O'tgan oy savdosi 0 bo'lsa, so'rov xato bermay, NULL qaytaradi. Bu kichik detal ko'p hisobotni buzadi.πΉ
100.0 β nuqta bilan. Butun sonlar bo'linsa, ba'zi bazalarda natija ham butun bo'lib qoladi: 0.25 o'rniga 0.π‘ Birinchi oyda
osish_foiz NULL bo'ladi β solishtiradigan oy yo'q. Hisobotda chiroyli ko'rinishi uchun: COALESCE(..., 0) yoki shunchaki chiziqcha.πΉ Window funksiyalar bo'yicha saytda 37 ta masala bor β
LAG, LEAD, SUM OVER, NTILE bilan mashq qilish uchun.π¬
LAG ni bilmagan bo'lsangiz, bugun bitta hisobotingizni shu bilan qayta yozib ko'ring.π― Endi amaliyot: Payme: oylik o'sish
Real keys β o'sha LAG bilan yechiladi π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
created_at ustuni timestamp. Β«WHERE created_at BETWEEN '2026-01-01' AND '2026-01-31'Β» β 31-yanvar soat 14:00 dagi yozuv natijaga tushadimi?
Anonymous Quiz
25%
Ha, tushadi
75%
Yo'q, tushmaydi
0%
Bazaga bog'liq
β»οΈ CTE: uzun so'rovni o'qiladigan qilish
Bir xil natijani subquery bilan ham olish mumkin, lekin CTE ni yuqoridan pastga o'qiysiz β xuddi retsept kabi.
RECURSIVE CTE β o'ziga murojaat qiladi. Ierarxiya uchun ideal: kim kimga bo'ysunadi?
π Qayerda kerak: tashkilot tuzilmasi, kategoriya daraxti, kommentlar ostidagi javoblar, yo'nalishlar zanjiri.
β οΈ Rekursiyada doim to'xtash sharti bo'lsin. Ma'lumotda halqa bo'lsa (A β B β A), so'rov cheksiz aylanadi.
π― Endi amaliyot: Uch bosqichli CTE zanjiri
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
WITH β so'rov ichidagi vaqtinchalik nom. Uch qavat ichma-ich subquery o'rniga bosqichma-bosqich mantiq:WITH faol AS (
SELECT id, name FROM customers
WHERE status = 'active'
),
buyurtma AS (
SELECT customer_id, SUM(amount) AS jami
FROM orders
WHERE created_at >= '2026-01-01'
GROUP BY customer_id
)
SELECT f.name, COALESCE(b.jami, 0) AS jami
FROM faol f
LEFT JOIN buyurtma b ON b.customer_id = f.id
ORDER BY jami DESC;
Bir xil natijani subquery bilan ham olish mumkin, lekin CTE ni yuqoridan pastga o'qiysiz β xuddi retsept kabi.
RECURSIVE CTE β o'ziga murojaat qiladi. Ierarxiya uchun ideal: kim kimga bo'ysunadi?
WITH RECURSIVE zanjir AS (
-- 1. Boshlang'ich: rahbari yo'q xodim
SELECT id, name, manager_id, 1 AS daraja
FROM employees
WHERE manager_id IS NULL
UNION ALL
-- 2. Har qadamda bir pog'ona pastga
SELECT e.id, e.name, e.manager_id, z.daraja + 1
FROM employees e
JOIN zanjir z ON e.manager_id = z.id
)
SELECT * FROM zanjir ORDER BY daraja;
π Qayerda kerak: tashkilot tuzilmasi, kategoriya daraxti, kommentlar ostidagi javoblar, yo'nalishlar zanjiri.
β οΈ Rekursiyada doim to'xtash sharti bo'lsin. Ma'lumotda halqa bo'lsa (A β B β A), so'rov cheksiz aylanadi.
π― Endi amaliyot: Uch bosqichli CTE zanjiri
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
β
Ertalabki test javobi: yo'q, tushmaydi
Ya'ni 31-yanvarning butun kuni β 00:00:01 dan 23:59:59 gacha β tushib qoladi.
Oyiga bir kun. Yiliga 12 kun. Hisobotda esa hech qanday xato belgisi yo'q: so'rov ishlaydi, raqam chiqadi, shunchaki kamroq.
Yodda tuting:
β
β
β
π‘ Amaliy maslahat: hisobot yozgach, natijani boshqa manba bilan solishtiring. Raqam 1β3% ga farq qilsa, birinchi gumondor β sana chegarasi.
π¬ Shu xato tufayli hisobotingiz noto'g'ri chiqqanmi? Izohda bo'lishing π
π― Endi amaliyot: Rekursiv: sotuvsiz kunlarni to'ldirish
Sana bilan ishlashning keyingi bosqichi π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
BETWEEN '2026-01-01' AND '2026-01-31' aslida shu degani:created_at >= 2026-01-01 00:00:00
created_at <= 2026-01-31 00:00:00
Ya'ni 31-yanvarning butun kuni β 00:00:01 dan 23:59:59 gacha β tushib qoladi.
Oyiga bir kun. Yiliga 12 kun. Hisobotda esa hech qanday xato belgisi yo'q: so'rov ishlaydi, raqam chiqadi, shunchaki kamroq.
Yodda tuting:
β
>= boshi AND < keyingi_boshi β har doim to'g'riβ
BETWEEN faqat date tipida xavfsizβ
<= '2026-01-31 23:59:59' β deyarli to'g'ri, lekin millisekundlar yo'qoladiπ‘ Amaliy maslahat: hisobot yozgach, natijani boshqa manba bilan solishtiring. Raqam 1β3% ga farq qilsa, birinchi gumondor β sana chegarasi.
π¬ Shu xato tufayli hisobotingiz noto'g'ri chiqqanmi? Izohda bo'lishing π
π― Endi amaliyot: Rekursiv: sotuvsiz kunlarni to'ldirish
Sana bilan ishlashning keyingi bosqichi π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
β Ertalabki masala: har kategoriyada top 3
Jadval:
Vazifa: har bir kategoriya bo'yicha eng ko'p sotilgan 3 ta mahsulotni chiqaring.
β οΈ Diqqat:
π― Bu masala Β«top N per groupΒ» deb ataladi va intervyularda doim uchraydi.
βοΈ Yechimingizni izohda yozing β kechqurun tahlil qilamiz π
π― Endi amaliyot: Har kategoriyada top 3 mahsulot
Masala saytda ham bor β yeching, tizim tekshiradi π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Jadval:
products(id, name, category, sales_count)Vazifa: har bir kategoriya bo'yicha eng ko'p sotilgan 3 ta mahsulotni chiqaring.
SELECT category, name, sales_count
FROM products
???
β οΈ Diqqat:
ORDER BY sales_count DESC LIMIT 3 ishlamaydi. U butun jadvaldan 3 ta qator beradi, har kategoriyadan emas.π― Bu masala Β«top N per groupΒ» deb ataladi va intervyularda doim uchraydi.
βοΈ Yechimingizni izohda yozing β kechqurun tahlil qilamiz π
π― Endi amaliyot: Har kategoriyada top 3 mahsulot
Masala saytda ham bor β yeching, tizim tekshiradi π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
π Qatorlarni ustunga aylantirish (pivot)
Boshliq so'radi: Β«Har bir mijoz bo'yicha oylar ustun bo'lib tursinΒ».
Bazada esa ma'lumot qator ko'rinishida. Yechim β
PostgreSQL da qisqaroq usul β FILTER:
O'qilishi ancha oson va tezroq ishlaydi.
π Xuddi shu usul bilan bitta so'rovda bir nechta ko'rsatkich hisoblanadi: konversiya, foiz nisbat, holatlar bo'yicha taqsimot. Har biri uchun alohida so'rov yozib, keyin qo'lda birlashtirish shart emas.
π‘ Ustunlar soni oldindan ma'lum bo'lmasa (masalan, kategoriyalar o'zgarib tursa), SQL o'zi dinamik ustun yasay olmaydi β bu kod tomonida qilinadi.
π― Endi amaliyot: To'lov holatlari bo'yicha pivot
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
Boshliq so'radi: Β«Har bir mijoz bo'yicha oylar ustun bo'lib tursinΒ».
Bazada esa ma'lumot qator ko'rinishida. Yechim β
CASE ni agregat ichiga qo'yish:SELECT
customer_id,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 1
THEN amount ELSE 0 END) AS yanvar,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 2
THEN amount ELSE 0 END) AS fevral,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 3
THEN amount ELSE 0 END) AS mart,
SUM(amount) AS jami
FROM sales
GROUP BY customer_id;
PostgreSQL da qisqaroq usul β FILTER:
SELECT
customer_id,
SUM(amount) FILTER (WHERE status = 'paid') AS tolangan,
SUM(amount) FILTER (WHERE status = 'pending') AS kutilmoqda,
COUNT(*) FILTER (WHERE amount > 1000000) AS yirik_buyurtma
FROM orders
GROUP BY customer_id;
O'qilishi ancha oson va tezroq ishlaydi.
π Xuddi shu usul bilan bitta so'rovda bir nechta ko'rsatkich hisoblanadi: konversiya, foiz nisbat, holatlar bo'yicha taqsimot. Har biri uchun alohida so'rov yozib, keyin qo'lda birlashtirish shart emas.
π‘ Ustunlar soni oldindan ma'lum bo'lmasa (masalan, kategoriyalar o'zgarib tursa), SQL o'zi dinamik ustun yasay olmaydi β bu kod tomonida qilinadi.
π― Endi amaliyot: To'lov holatlari bo'yicha pivot
O'qib tushundingiz β endi o'zingiz yozib ko'ring π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
β
Yechim: har kategoriyada top 3
Nega LIMIT ishlamaydi? Chunki
Teng natijalar bo'lsa-chi? Ikki mahsulot bir xil sotilgan bo'lsa,
β οΈ Barqarorlik uchun
Aks holda bir xil so'rov har safar boshqa natija berishi mumkin β va buni tushuntirish qiyin bo'ladi.
π¬ Siz
π― Endi amaliyot: Har guruhdan 2 ta (windowsiz)
Bu safar window funksiyasiz β qiyinroq variant π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz
WITH r AS (
SELECT category, name, sales_count,
ROW_NUMBER() OVER (
PARTITION BY category
ORDER BY sales_count DESC
) AS rn
FROM products
)
SELECT category, name, sales_count
FROM r
WHERE rn <= 3
ORDER BY category, rn;
Nega LIMIT ishlamaydi? Chunki
LIMIT butun natijaga qo'llanadi, guruhga emas. SQL da Β«har guruhdan N taΒ» degan to'g'ridan-to'g'ri konstruksiya yo'q β shuning uchun avval raqamlaymiz, keyin filtrlaymiz.Teng natijalar bo'lsa-chi? Ikki mahsulot bir xil sotilgan bo'lsa,
ROW_NUMBER ulardan birini tanlaydi (qaysi birini β aniq emas). Ikkalasi ham kerak bo'lsa DENSE_RANK ishlating.β οΈ Barqarorlik uchun
ORDER BY ga ikkinchi ustun qo'shing:ORDER BY sales_count DESC, id
Aks holda bir xil so'rov har safar boshqa natija berishi mumkin β va buni tushuntirish qiyin bo'ladi.
π¬ Siz
ROW_NUMBER ni ishlatdingizmi yoki boshqa yo'l topdingizmi?π― Endi amaliyot: Har guruhdan 2 ta (windowsiz)
Bu safar window funksiyasiz β qiyinroq variant π
ββββββββ
πΎ Amaliyot: sqlmaster.uz
π’ @sqlmasteruz