SQL Master πŸ‡ΊπŸ‡Ώ
21 subscribers
1 photo
1 video
54 links
SQL'ni video ko'rib emas, yozib o'rganing. 200+ real masala β€” Uzum, Click, taksi mavzularida. Yozasiz, tizim tekshiradi.

πŸ‘‰ sqlmaster.uz

Admin: @fast_support_admin
Download Telegram
β˜• Ertalabki masala: ketma-ket kunlar

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 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
β˜• Ertalabki savol: qaysi biri tezroq?

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 tezroq
B) EXISTS tezroq
C) 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
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%' β€” ishlaydi
LIKE '%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 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: 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
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

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

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

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: 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 β€” 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

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
Qaysi so'rov Β«buyurtma bermagan mijozlarΒ» uchun eng xavfsiz?
Anonymous Quiz
0%
WHERE id NOT IN (SELECT customer_id FROM orders)
0%
Ikkalasi ham bir xil xavfsiz
πŸ’Ό SQL suhbatida eng ko'p beriladigan 7 savol

1. INNER va LEFT JOIN farqi?
INNER β€” faqat mos kelganlar. LEFT β€” chap jadvalning hammasi, mos kelmasa NULL.

2. WHERE va HAVING?
WHERE guruhlashdan oldin qatorlarni, HAVING guruhlashdan keyin guruhlarni filtrlaydi.

3. COUNT(*) va COUNT(ustun)?
Birinchisi qatorlarni, ikkinchisi NULL bo'lmagan qiymatlarni sanaydi.

4. UNION va UNION ALL?
UNION dublikatlarni olib tashlaydi (saralash kerak β€” sekinroq), UNION ALL hammasini qo'shadi.

5. Ikkinchi eng yuqori maoshni toping.
SELECT MAX(salary) FROM employees
WHERE salary < (SELECT MAX(salary) FROM employees);

Yoki DENSE_RANK() = 2 bilan β€” teng maoshlar bo'lsa shu to'g'riroq.

6. Dublikatlarni qanday topasiz?
GROUP BY ustun HAVING COUNT(*) > 1

7. Index nima va qachon ishlamaydi?
Qidiruvni tezlashtiradigan tuzilma. Ustunga funksiya qo'llansa, LIKE '%...' bo'lsa yoki tip mos kelmasa ishlamaydi.

πŸ’‘ Maslahat: suhbatda javobni aytib qo'ya qolmang β€” ovoz chiqarib fikrlang. Β«Avval NULL bormi deb tekshirardim, keyin...Β» degan gap to'g'ri javobdan ko'ra kuchliroq taassurot qoldiradi.

πŸ’¬ Sizdan suhbatda qanday SQL savoli so'ralgan? Izohda yozing β€” keyingi postlarda tahlil qilamiz πŸ‘‡

🎯 Endi amaliyot: Click: to'lovlar holati bo'yicha hisobot
O'qib tushundingiz β€” endi o'zingiz yozib ko'ring πŸ‘‡

βž–βž–βž–βž–βž–βž–βž–βž–
πŸ’Ύ Amaliyot: sqlmaster.uz
πŸ“’ @sqlmasteruz
🏁 10 kun: nimalarni ko'rib chiqdik

βœ… NULL tuzoqlari β€” NOT IN, COUNT, uch qiymatli mantiq
βœ… So'rovning haqiqiy bajarilish tartibi, WHERE va HAVING
βœ… Window funksiyalar: ROW_NUMBER, RANK, DENSE_RANK, LAG
βœ… Dublikatlarni topish va o'chirish, DISTINCT antipatterni
βœ… Gaps and islands β€” ketma-ket kunlar
βœ… Index qachon ishlamaydi, EXPLAIN ANALYZE
βœ… Sana tuzoqlari, BETWEEN va vaqt zonasi
βœ… CTE va rekursiya, pivot, top N per group

Bu β€” bir oylik kurs hajmidagi material. Lekin o'qish bilan tugamaydi.

Premium nima beradi (29 000 so'm/oy):
πŸ”Ή Barcha 195 ta masala (bepul rejada β€” 50 ta)
πŸ”Ή 4 ta dialekt: PostgreSQL, MySQL, SQL Server, Oracle. Ishingizda qaysi biri bo'lsa β€” shunda mashq qilasiz
πŸ”Ή Har masalada 2-3 ta yechim: oddiydan optimalgacha, index tavsiyalari va query plan tahlili bilan
πŸ”Ή Kompaniya track'lari: Click, Payme, Uzum, EPAM, banklar uchun intervyu to'plamlari
πŸ”Ή Yillik obunada 2 oy bepul

πŸ’‘ Avval bepul 50 masalani yeching. Yoqsa β€” Premium'ga o'tasiz, yoqmasa hech narsa yo'qotmaysiz.

βž–βž–βž–βž–βž–βž–βž–βž–
πŸ’Ύ Amaliyot: sqlmaster.uz
πŸ“’ @sqlmasteruz
β˜• Ertalabki masala: oxirgi yozuv

Jadval: payments(id, client_id, paid_at, amount)

Vazifa: har bir mijozning eng oxirgi to'lovini chiqaring β€” mijoz, sana va summa.

SELECT client_id, paid_at, amount
FROM payments
???


⚠️ MAX(paid_at) bilan GROUP BY qilsangiz, summa qaysi to'lovniki ekani yo'qoladi. Bu β€” eng ko'p uchraydigan tuzoq.

🎯 Β«Har guruhdan oxirgi qatorΒ» β€” amaliy ishda haftada bir marta kerak bo'ladigan naqsh.

✍️ Yechimingizni izohda yozing, 20:00 da uch xil usulni ko'rsataman πŸ‘‡

🎯 Endi amaliyot: Har mijozning oxirgi to'lovi
Masala saytda tayyor β€” yeching, tizim javobingizni tekshiradi πŸ‘‡

βž–βž–βž–βž–βž–βž–βž–βž–
πŸ’Ύ Amaliyot: sqlmaster.uz
πŸ“’ @sqlmasteruz
πŸ”— JOIN turlari: qachon qaysi biri

INNER JOIN β€” faqat ikkala jadvalda ham mos keladigan qatorlar.
Buyurtma bergan mijozlar.

LEFT JOIN β€” chap jadvalning hammasi, mos kelmasa NULL.
Barcha mijozlar, buyurtmasi bor-yo'qligidan qat'i nazar.

RIGHT JOIN β€” LEFT ning teskarisi. Amalda kam ishlatiladi: jadvallar o'rnini almashtirib LEFT yozish o'qilishi osonroq.

FULL OUTER JOIN β€” ikkala tomonning hammasi. Ikki tizim ma'lumotini solishtirganda foydali: qaysi biri qayerda yo'q.

CROSS JOIN β€” har qator har qator bilan. 5 Γ— 4 = 20 qator. Kalendar Γ— filial kabi to'liq matritsa yasashda kerak.

Eng ko'p uchraydigan ehtiyoj β€” Β«mos kelmaganlarni topishΒ»:
SELECT c.*
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;

Bu β€” Β«anti-joinΒ» naqshi. LEFT JOIN qilib, keyin NULL qolganlarni olasiz.

⚠️ Venn diagrammalarini unuting. JOIN to'plamlarni kesishtirmaydi β€” u qatorlarni juftlashtiradi. Shuning uchun 1:N bog'lanishda qatorlar soni oshadi.

🎯 Endi amaliyot: A da bor, B da yo'q
Anti-join naqshini mustahkamlang πŸ‘‡

βž–βž–βž–βž–βž–βž–βž–βž–
πŸ’Ύ Amaliyot: sqlmaster.uz
πŸ“’ @sqlmasteruz
βœ… Yechim: har guruhdan oxirgi qator β€” 3 usul

1. ROW_NUMBER (universal, hamma bazada ishlaydi)
WITH r AS (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY client_id ORDER BY paid_at DESC
) AS rn
FROM payments
)
SELECT client_id, paid_at, amount FROM r WHERE rn = 1;


2. DISTINCT ON (faqat PostgreSQL, eng qisqasi)
SELECT DISTINCT ON (client_id) client_id, paid_at, amount
FROM payments
ORDER BY client_id, paid_at DESC;


3. Korrelyatsion subquery (eski bazalar uchun)
SELECT p.*
FROM payments p
WHERE p.paid_at = (
SELECT MAX(paid_at) FROM payments
WHERE client_id = p.client_id
);


❌ Nega GROUP BY bilan bo'lmaydi?
SELECT client_id, MAX(paid_at), amount   -- xato
FROM payments GROUP BY client_id;

amount qaysi qatorniki? Baza bilmaydi. PostgreSQL xato beradi, MySQL esa tasodifiy qiymat qaytaradi β€” bu yomonroq, chunki so'rov Β«ishlaydiΒ» va xato sezilmaydi.

⚠️ Bir mijozda ikki to'lov bir xil vaqtda bo'lsa, 1 va 2-usul bittasini tanlaydi, 3-usul esa ikkalasini qaytaradi. Shuni hisobga oling.

🎯 Endi amaliyot: Mijozning birinchi va oxirgi buyurtmasi
Endi ikkalasini bitta so'rovda chiqaring πŸ‘‡

βž–βž–βž–βž–βž–βž–βž–βž–
πŸ’Ύ Amaliyot: sqlmaster.uz
πŸ“’ @sqlmasteruz