JOIN lar
1-bobda data nima uchun table larga bo'linishi tushuntirilgan edi: har bir fakt aynan bir marta saqlanadi, shunda u o'zi bilan zid bo'lolmaydi. JOIN lar — shu kelishuvning ikkinchi yarmi: ular bo'laklarni bitta query davomida qayta birlashtiradi.
Bu — talabalar SQL ni yo "tushunib oladigan", yo indamay tushunmay qoladigan bob, shuning uchun shoshilmang va query yozishdan oldin doim ikkala table ni chizib bering.
JOIN nima uchun kerak
enrollments aslida nima saqlashiga qarang:
SELECT * FROM enrollments LIMIT 3;
enrollment_idstudent_idcourse_idteacher_idenrolled_atgradestatus
11142025-09-0592completed 21222025-09-0588completed 31512026-02-03NULLactive
Buni hech kim o'qiy olmaydi. U "1 4 bilan 1 ni o'qidi" deydi — uchta raqam va hech qanday ma'no. Odamga "Aziza Python Basics ni Sardor Yoqubov bilan o'qidi" kerak. Birinchi table ni ikkinchi jumlaga aylantirish — JOIN ning butun vazifasi.
JOIN chap table ning har bir row ini oladi, o'ng table dan ON sharti to'g'ri bo'lgan row larni qidiradi va mos row larni yonma-yon yopishtirib bitta kengroq row qiladi. JOIN turlari orasida faqat bitta narsa farq qiladi: mos keluvchi topmagan row ga nima bo'ladi.
INNER JOIN
INNER JOIN faqat ikkala tomonda mos kelgan row larni qoldiradi. U standart — oddiy JOIN INNER JOIN degani.
SELECT s.first_name, s.last_name, e.grade, e.status FROM enrollments e INNER JOIN students s ON e.student_id = s.student_id ORDER BY e.enrollment_id LIMIT 5;
| first_name | last_name | grade | status |
|---|---|---|---|
| Rustam | Nazarov | 88 | completed |
| Sardor | Karimov | NaN | active |
| Gulnora | Yusupova | 75 | completed |
| Sardor | Karimov | NaN | active |
| Kamola | Umarova | NaN | active |
5 qator
1 ms
- Menga kerak column lar qaysi table larda?
- Ularning umumiy column i qaysi? (Foreign key larga qarang.)
- Qaysi table "ko'p" tomon?
FROMni o'shandan boshlang. - Mos kelmagan row lar saqlanishi kerakmi? Ha bo'lsa →
LEFT JOIN. Yo'q bo'lsa →INNER JOIN.
ON, USING va eski vergul sintaksisi
-- 1. ON — doim ishlaydi va column nomlari har xil bo'lsa yagona variant SELECT s.first_name, e.grade FROM students s JOIN enrollments e ON s.student_id = e.student_id; -- 2. USING — qisqaroq, lekin faqat IKKALA column nomi bir xil bo'lganda SELECT s.first_name, e.grade FROM students s JOIN enrollments e USING (student_id); -- 3. Eski vergul sintaksisi — yashirin inner join. Buni o'rgatmang. SELECT s.first_name, e.grade FROM students s, enrollments e WHERE s.student_id = e.student_id;
1-natija
| first_name | grade |
|---|---|
| Rustam | 88 |
| Sardor | NaN |
| Gulnora | 75 |
| Sardor | NaN |
| Kamola | NaN |
| Ulug'bek | 83 |
| Malika | NaN |
| Sevara | 77 |
| Dilnoza | 63 |
| Sevara | NaN |
| Otabek | 67 |
| Kamola | 62 |
| Gulnora | 77 |
| Zulfiya | 79 |
| Zulfiya | 80 |
… 2500 qatordan birinchi 15 tasi
2500 qator
2-natija
| first_name | grade |
|---|---|
| Rustam | 88 |
| Sardor | NaN |
| Gulnora | 75 |
| Sardor | NaN |
| Kamola | NaN |
| Ulug'bek | 83 |
| Malika | NaN |
| Sevara | 77 |
| Dilnoza | 63 |
| Sevara | NaN |
| Otabek | 67 |
| Kamola | 62 |
| Gulnora | 77 |
| Zulfiya | 79 |
| Zulfiya | 80 |
… 2500 qatordan birinchi 15 tasi
2500 qator
3-natija
| first_name | grade |
|---|---|
| Rustam | 88 |
| Sardor | NaN |
| Gulnora | 75 |
| Sardor | NaN |
| Kamola | NaN |
| Ulug'bek | 83 |
| Malika | NaN |
| Sevara | 77 |
| Dilnoza | 63 |
| Sevara | NaN |
| Otabek | 67 |
| Kamola | 62 |
| Gulnora | 77 |
| Zulfiya | 79 |
| Zulfiya | 80 |
… 2500 qatordan birinchi 15 tasi
2500 qator
4 ms
:::gotcha ⚠️ Nega vergul sintaksisi zamonaviy kodda taqiqlangan
WHERE qatorini unutsangiz, xato chiqmaydi — CROSS JOIN chiqadi: har bir student har bir enrollment bilan juftlanadi, 10 × 20 = 200 ta ma'nosiz row. Aniq JOIN ... ON da esa join sharti join ning yonida turadi va yo'qolib qololmaydi. Vergul bilan outer join yozishning ham iloji yo'q. JOIN ... ON ishlating.
:::
U ikkala table da nomi tasodifan bir xil bo'lgan har bir column bo'yicha join qiladi. Kelasi yili ikkita table ga created_at column i qo'shilsa, kodbazadagi har bir NATURAL JOIN ning ma'nosi indamay o'zgaradi. Shartni doim aniq yozing.
LEFT JOIN
LEFT JOIN chap table ning har bir row ini saqlaydi — mos kelgan-kelmaganidan qat'i nazar. Mos kelmagan joyda o'ng table ning column lari NULL bo'lib qaytadi.
Bu aynan 4-bobdagi yo'qolgan course ning yechimi:
SELECT c.title, COUNT(e.enrollment_id) AS enrollments, ROUND(AVG(e.grade), 1) AS avg_grade FROM courses c LEFT JOIN enrollments e ON c.course_id = e.course_id GROUP BY c.course_id, c.title ORDER BY enrollments DESC;
| title | enrollments | avg_grade |
|---|---|---|
| Linear Algebra | 200 | 68.3 |
| Python Basics | 193 | 79.2 |
| Financial Analysis | 189 | 74.7 |
| Probability | 188 | 65.6 |
| Java Basics | 187 | 73.9 |
| SQL for Analytics | 186 | 74.3 |
| Graphic Design | 179 | 73.5 |
| Statistics 101 | 174 | 63.6 |
| Web Development | 174 | 75.2 |
| Project Management | 170 | 75.1 |
| Data Visualization | 167 | 74.2 |
| Machine Learning | 167 | 69.4 |
| Excel for Business | 165 | 79.9 |
| UX Design | 161 | 76.1 |
| Deep Learning | 0 | NaN |
15 qator
1 ms
Deep Learning0NULL
Deep Learning nihoyat paydo bo'ldi, 0 bilan. Aynan shu bitta row odatda butun hisobotdagi eng qimmatli qator — hech kim yozilmagan course rahbariyat ko'rishi kerak bo'lgan narsaning o'zi.
LEFT JOIN Deep Learning uchun bitta row hosil qiladi, unda enrollment column larining hammasi NULL. COUNT(*) row larni sanaydi, shuning uchun u 1 qaytaradi — nol student li course bitta student bor deb ko'rsatiladi. COUNT(e.enrollment_id) esa NULL bo'lmagan qiymatlarni sanaydi va to'g'ri 0 qaytaradi.
Qoida: LEFT JOIN dan keyin doim o'ng table ning column ini sanang, hech qachon COUNT(*) ni emas. Bu real, tez-tez uchraydigan production xatosi va sevimli intervyu savoli.
Xuddi shu shakl NULL teacher uchun ham ishlaydi:
SELECT e.enrollment_id, COALESCE(t.full_name, '(biriktirilmagan)') AS teacher FROM enrollments e LEFT JOIN teachers t ON e.teacher_id = t.teacher_id WHERE e.enrollment_id IN (18, 19, 20);
| enrollment_id | teacher |
|---|---|
| 18 | Zulfiya Saidova |
| 19 | Malika Umarova |
| 20 | Malika Umarova |
3 qator
0 ms
RIGHT va FULL OUTER JOIN
RIGHT JOIN — ko'zgudagi aksi: u o'ng table ning har bir row ini saqlaydi. FULL OUTER JOIN ikkala tomonning ham hamma row ini saqlaydi va yetishmagan tomonni NULL bilan to'ldiradi.
Bu muhim emas, chunki har qanday RIGHT JOIN — table lari almashtirilgan LEFT JOIN:
A RIGHT JOIN B ON ... ≡ B LEFT JOIN A ON ...
Amalda RIGHT JOIN ni deyarli hech kim yozmaydi: har bir join bitta asosiy table ni chapdan kengaytirib borsa, query ni o'qish ancha oson. LEFT JOIN ni o'rgating, RIGHT JOIN borligini aytib o'ting va davom eting.
FULL OUTER JOIN analytics da kam uchraydi, lekin solishtirish uchun haqiqatan foydali — bir xil yozuvlarni saqlashi kerak bo'lgan ikkita tizimni taqqoslab, qaysi tomonda nima yetishmayotganini topish. Qo'llab-quvvatlanmagan joyda uni ikkita LEFT JOIN va UNION bilan yasash mumkin (9-bob).
Anti-join: mos kelmagan row lar
"Qaysi X da Y yo'q?" — analytics dagi eng ko'p uchraydigan savollardan biri: hech qachon buyurtma bermagan mijozlar, sotilmagan mahsulotlar, yozilmagan student lar. Pattern doim bir xil — LEFT JOIN qiling, keyin o'ng tomoni NULL bo'lib qaytgan row larni qoldiring.
SELECT c.course_id, c.title FROM courses c LEFT JOIN enrollments e ON c.course_id = e.course_id WHERE e.enrollment_id IS NULL;
| course_id | title |
|---|---|
| 12 | Deep Learning |
1 qator
1 ms
-- (a) LEFT JOIN + IS NULL — odatda eng tezi SELECT c.title FROM courses c LEFT JOIN enrollments e ON c.course_id = e.course_id WHERE e.enrollment_id IS NULL; -- (b) NOT EXISTS — maqsad eng aniq, NULL ga nisbatan xavfsiz SELECT c.title FROM courses c WHERE NOT EXISTS (SELECT 1 FROM enrollments e WHERE e.course_id = c.course_id); -- (c) NOT IN — faqat enrollments.course_id NOT NULL bo'lgani uchun xavfsiz. Mo'rt. SELECT c.title FROM courses c WHERE c.course_id NOT IN (SELECT course_id FROM enrollments);
1-natija
| title |
|---|
| Deep Learning |
1 qator
2-natija
| title |
|---|
| Deep Learning |
1 qator
3-natija
| title |
|---|
| Deep Learning |
1 qator
1 ms
:::tip 💡 Tekshiradigan column ni ehtiyot bo'lib tanlang
(a) pattern ida o'ng table ning real data da hech qachon NULL bo'lmaydigan column ini tekshiring — uning primary key i xavfsiz tanlov. e.grade kabi NULL bo'lishi mumkin column ni tekshirsangiz, mavjud lekin baholanmagan enrollment lar ham tushib qoladi va javob noto'g'ri bo'ladi.
:::
Uch va undan ko'p table ni JOIN qilish
JOIN lar zanjir bo'ladi: bitta join ning natijasi — table, u keyingisiga join qilinadi. Junction table (enrollments) dan boshlang va lookup table larni unga osib chiqing.
SELECT s.first_name || ' ' || s.last_name AS student, c.title AS course, COALESCE(t.full_name, '(yo''q)') AS teacher, e.grade, e.status FROM enrollments e JOIN students s ON e.student_id = s.student_id JOIN courses c ON e.course_id = c.course_id LEFT JOIN teachers t ON e.teacher_id = t.teacher_id ORDER BY e.enrollment_id LIMIT 6;
| student | course | teacher | grade | status |
|---|---|---|---|---|
| Rustam Nazarov | Web Development | Dilshod Karimov | 88 | completed |
| Sardor Karimov | Machine Learning | Jasur Toshev | NaN | active |
| Gulnora Yusupova | Statistics 101 | Kamola Ergasheva | 75 | completed |
| Sardor Karimov | SQL for Analytics | Nodira Alimova | NaN | active |
| Kamola Umarova | Data Visualization | (yo'q) | NaN | active |
| Ulug'bek Qodirov | Excel for Business | Sevara Aliyeva | 83 | completed |
6 qator
1 ms
Tartib muhim. Agar FROM courses c LEFT JOIN enrollments e ... JOIN students s ON e.student_id = s.student_id deb yozsangiz, Deep Learning row i (uning e.student_id i NULL) hech qanday student ga mos kelmaydi va inner join uni o'chiradi. LEFT JOIN qilgan barcha ish behuda ketadi. Bir marta LEFT ga o'tsangiz, zanjirning qolgan qismida ham LEFT da qoling.
CROSS JOIN va SELF JOIN
CROSS JOIN
A ning har bir row i B ning har bir row i bilan — shartsiz. Natijada m × n ta row bo'ladi.
SELECT COUNT(*) FROM students CROSS JOIN courses; -- 10 × 6 = 60
U deyarli doim tasodif (unutilgan ON), lekin bitta haqiqiy foydasi bor: nol larni ko'rsatish uchun to'liq to'r qurish. "Har bir course, har bir oy, hatto bo'sh birikmalar ham" ni yolg'iz GROUP BY bilan olishning iloji yo'q — avval to'rni yaratish, keyin unga real data ni LEFT JOIN qilish kerak.
SELF JOIN
Table ning o'ziga o'zi join qilinishi; engine nusxalarni ajrata olishi uchun ikkita har xil alias ishlatiladi. Uni bitta table ichida row larni solishtirish uchun ishlating.
-- Bir shaharda yashaydigan student juftliklari -- (a.student_id < b.student_id o'z-o'ziga juftlanishni VA takroriy aksni to'sadi) SELECT a.first_name AS student_a, b.first_name AS student_b, a.city FROM students a JOIN students b ON a.city = b.city AND a.student_id < b.student_id ORDER BY a.city;
| student_a | student_b | city |
|---|---|---|
| Dilnoza | Akmal | Andijan |
| Dilnoza | Akmal | Andijan |
| Dilnoza | Aziza | Andijan |
| Dilnoza | Aziza | Andijan |
| Dilnoza | Doston | Andijan |
| Dilnoza | Doston | Andijan |
| Dilnoza | Gulnora | Andijan |
| Dilnoza | Jasur | Andijan |
| Dilnoza | Jasur | Andijan |
| Dilnoza | Kamola | Andijan |
| Dilnoza | Kamola | Andijan |
| Dilnoza | Kamola | Andijan |
| Dilnoza | Malika | Andijan |
| Dilnoza | Otabek | Andijan |
| Dilnoza | Otabek | Andijan |
… 6550 qatordan birinchi 15 tasi
6550 qator
4 ms
student_astudent_bcity
BekzodZarinaSamarkand AzizaJasurTashkent AzizaOtabekTashkent JasurOtabekTashkent
Sevara yo'q, chunki uning shahri NULL, NULL = NULL esa UNKNOWN — 1-bobdagi NULL qoidasi ON ichida ham xuddi WHERE dagidek ishlaydi.
a.student_id <> b.student_id bilan (Aziza, Jasur) ham, (Jasur, Aziza) ham chiqadi — har bir juftlik ikki marta. < esa aynan bitta yo'nalishni qoldiradi. Bu usul har bir self-join topshirig'ida uchraydi; intervyu oluvchilar aynan shuni qidiradi.
Yana bir klassik self-join — xodim/rahbar iyerarxiyasi: FROM employees e JOIN employees m ON e.manager_id = m.employee_id.
Fan-out: row larni ko'paytiruvchi jimjit xato
Bu — JOIN dagi eng qimmat xato, chunki query mukammal ishlaydi va ishonarli ko'rinadigan, lekin shunchaki noto'g'ri raqam qaytaradi.
SELECT COUNT(*) FROM students; -- 10 SELECT COUNT(*) FROM students s JOIN enrollments e ON s.student_id = e.student_id; -- 20 ← !! SELECT COUNT(DISTINCT s.student_id) FROM students s JOIN enrollments e ON s.student_id = e.student_id; -- 10
1-natija
| COUNT(*) |
|---|
| 300 |
1 qator
2-natija
| COUNT(*) |
|---|
| 2 500 |
1 qator
3-natija
| COUNT(DISTINCT s.student_id) |
|---|
| 300 |
1 qator
1 ms
"Ko'p" tomonga join qilish har bir student row ini takrorladi — har bir enrollment uchun bir marta. Endi sanash student larni emas, enrollment larni sanayapti. Pul bilan bo'lsa, battarroq:
-- Teacher larga to'lanadigan umumiy oylik qancha? SELECT SUM(salary) FROM teachers; -- 36 500 000 — to'g'ri -- Xuddi shu savol, lekin kimdir course bo'yicha filtrlash uchun enrollments ni join qilgan SELECT SUM(t.salary) FROM teachers t JOIN enrollments e ON t.teacher_id = e.teacher_id; -- 175 600 000 — deyarli 5 barobar ko'p, va hech qayerda xato yo'q
1-natija
| SUM(salary) |
|---|
| 117 300 000 |
1 qator
2-natija
| SUM(t.salary) |
|---|
| 23 933 000 000 |
1 qator
1 ms
Nodira ning oyligi 6 marta sanaldi (u 6 ta enrollment da bor), Rustam niki 5 marta va hokazo. Hisobot professional ko'rinadi va 139 million ga xato.
- Aniqlash: JOIN qo'shishdan oldin va keyin
SELECT COUNT(*)ni ishga tushiring. Raqam o'sgan bo'lsa, chap tomondagi row lar takrorlangan — o'sha tomondan hisoblagan har bir aggregate endi shishirilgan. - To'g'ri tuzatish: join dan oldin aggregate qiling. CTE da ko'p tomonni har bir key uchun bitta row ga siqing, keyin o'shani join qiling (6-bob):
WITH per_teacher AS ( SELECT teacher_id, COUNT(*) AS lessons FROM enrollments GROUP BY teacher_id ) SELECT t.full_name, t.salary, p.lessons FROM teachers t LEFT JOIN per_teacher p USING (teacher_id); DISTINCTbilan "tuzatmang".SUM(DISTINCT salary)tasodifan bir xil oylik oladigan ikkita teacher ni bittaga qo'shib yuboradi.DISTINCTalomatni yashiradi va yangi xato yaratadi.
Outer join da ON va WHERE
INNER JOIN da shartni qayerga qo'yish farq qilmaydi. LEFT JOIN da esa u javobni butunlay o'zgartiradi, va bu eng yuqori darajadagi intervyu savollaridan biri.
-- (A) shart ON ichida: O'NG table ni join dan OLDIN filtrlaydi. -- Har bir course baribir saqlanadi. SELECT c.title, COUNT(e.enrollment_id) AS completed FROM courses c LEFT JOIN enrollments e ON c.course_id = e.course_id AND e.status = 'completed' GROUP BY c.course_id, c.title; -- (B) shart WHERE ichida: NATIJANI join dan KEYIN filtrlaydi. -- Tugatilgan enrollment i yo'q course lar o'chadi — LEFT JOIN -- indamay INNER JOIN ga aylandi. SELECT c.title, COUNT(e.enrollment_id) AS completed FROM courses c LEFT JOIN enrollments e ON c.course_id = e.course_id WHERE e.status = 'completed' GROUP BY c.course_id, c.title;
1-natija
| title | completed |
|---|---|
| Python Basics | 130 |
| SQL for Analytics | 134 |
| Statistics 101 | 81 |
| Data Visualization | 111 |
| Machine Learning | 110 |
| Web Development | 114 |
| Excel for Business | 120 |
| Project Management | 118 |
| UX Design | 112 |
| Graphic Design | 139 |
| Linear Algebra | 116 |
| Deep Learning | 0 |
| Java Basics | 123 |
| Financial Analysis | 125 |
| Probability | 101 |
15 qator
2-natija
| title | completed |
|---|---|
| Python Basics | 130 |
| SQL for Analytics | 134 |
| Statistics 101 | 81 |
| Data Visualization | 111 |
| Machine Learning | 110 |
| Web Development | 114 |
| Excel for Business | 120 |
| Project Management | 118 |
| UX Design | 112 |
| Graphic Design | 139 |
| Linear Algebra | 116 |
| Java Basics | 123 |
| Financial Analysis | 125 |
| Probability | 101 |
14 qator
2 ms
Deep Learning0row yo'qoladi
:::info 📌 Qoida
LEFT JOIN da: o'ng table ga oid shartlar ON ga, chap table ga oid shartlar WHERE ga yoziladi. O'ng table sharti WHERE ga tushsa, outer join yana inner join ga aylanadi — istisno faqat IS NULL, u anti-join pattern i va ataylab qilinadi.
:::
Mashqlar to'plami
-- 1. Har bir student va u oladigan course lar soni (nol bo'lsa ham) SELECT s.first_name, COUNT(e.enrollment_id) AS courses FROM students s LEFT JOIN enrollments e ON s.student_id = e.student_id GROUP BY s.student_id, s.first_name ORDER BY courses DESC; -- 2. Teacher lar va ular olib boradigan enrollment lar soni SELECT t.full_name, t.subject, COUNT(e.enrollment_id) AS lessons FROM teachers t LEFT JOIN enrollments e ON t.teacher_id = e.teacher_id GROUP BY t.teacher_id, t.full_name, t.subject ORDER BY lessons DESC; -- 3. 'SQL for Analytics' ni qaysi student lar oladi? SELECT s.first_name, s.last_name, e.grade FROM enrollments e JOIN students s ON e.student_id = s.student_id JOIN courses c ON e.course_id = c.course_id WHERE c.title = 'SQL for Analytics' ORDER BY e.grade DESC; -- 4. Hech kim yozilmagan course lar (anti-join) SELECT c.title FROM courses c LEFT JOIN enrollments e ON c.course_id = e.course_id WHERE e.enrollment_id IS NULL; -- 5. Kategoriya bo'yicha daromad (narx har bir enrollment uchun bir marta) SELECT c.category, COUNT(*) AS enrollments, SUM(c.price) AS revenue FROM enrollments e JOIN courses c ON e.course_id = c.course_id GROUP BY c.category ORDER BY revenue DESC; -- 6. Shahar bo'yicha o'rtacha baho SELECT COALESCE(s.city,'(unknown)') AS city, COUNT(e.grade) AS graded, ROUND(AVG(e.grade),1) AS avg_grade FROM students s JOIN enrollments e ON s.student_id = e.student_id GROUP BY s.city ORDER BY avg_grade DESC; -- 7. To'liq o'qishli enrollment hisoboti SELECT s.first_name || ' ' || s.last_name AS student, c.title AS course, COALESCE(t.full_name,'(yo''q)') AS teacher, e.grade, e.status FROM enrollments e JOIN students s ON e.student_id = s.student_id JOIN courses c ON e.course_id = c.course_id LEFT JOIN teachers t ON e.teacher_id = t.teacher_id ORDER BY student, course; -- 8. Bir shahardagi student lar (self join, faqat bitta yo'nalish) SELECT a.first_name AS a, b.first_name AS b, a.city FROM students a JOIN students b ON a.city = b.city AND a.student_id < b.student_id;
1-natija
| first_name | courses |
|---|---|
| Zulfiya | 19 |
| Shohrux | 17 |
| Sardor | 16 |
| Gulnora | 16 |
| Otabek | 15 |
| Shohrux | 15 |
| Aziz | 15 |
| Nilufar | 15 |
| Gulnora | 15 |
| Shahnoza | 15 |
| Malika | 14 |
| Zulfiya | 14 |
| Akmal | 14 |
| Kamola | 14 |
| Kamola | 14 |
… 300 qatordan birinchi 15 tasi
300 qator
2-natija
| full_name | subject | lessons |
|---|---|---|
| Kamola Ergasheva | Statistics | 286 |
| Sardor Qodirov | Programming | 276 |
| Sevara Aliyeva | Business | 273 |
| Dilshod Karimov | Programming | 260 |
| Nodira Alimova | Data Science | 258 |
| Zulfiya Saidova | Statistics | 256 |
| Jasur Toshev | Data Science | 251 |
| Otabek Rahimov | Business | 241 |
| Gulnora Yusupova | Design | 168 |
| Malika Umarova | Design | 164 |
| Rustam Halilov | Databases | 0 |
| Akmal Nazarov | Databases | 0 |
12 qator
3-natija
| first_name | last_name | grade |
|---|---|---|
| Gulnora | Qodirova | 96 |
| Zulfiya | Yusupova | 95 |
| Kamola | Tosheva | 94 |
| Ulug'bek | Yusupov | 92 |
| Rustam | Saidov | 91 |
| Shahnoza | Rahimova | 91 |
| Doston | Rahimov | 90 |
| Shohrux | Umarov | 90 |
| Shohrux | Alimov | 90 |
| Kamola | Ergasheva | 90 |
| Kamola | Karimova | 90 |
| Gulnora | Ergasheva | 89 |
| Otabek | Saidov | 89 |
| Otabek | Umarov | 88 |
| Aziza | Nazarova | 88 |
… 186 qatordan birinchi 15 tasi
186 qator
4-natija
| title |
|---|
| Deep Learning |
1 qator
5-natija
| category | enrollments | revenue |
|---|---|---|
| Business | 524 | 720 000 000 |
| Math | 562 | 683 800 000 |
| Programming | 554 | 646 750 000 |
| Data | 520 | 541 250 000 |
| Design | 340 | 306 900 000 |
5 qator
6-natija
| city | graded | avg_grade |
|---|---|---|
| Samarkand | 233 | 76.7 |
| Nukus | 154 | 73.2 |
| Namangan | 173 | 73.1 |
| Karshi | 154 | 73.1 |
| Andijan | 134 | 72.8 |
| Bukhara | 238 | 72.2 |
| Tashkent | 495 | 72 |
| Fergana | 208 | 71.9 |
| (unknown) | 37 | 71.8 |
9 qator
7-natija
| student | course | teacher | grade | status |
|---|---|---|---|---|
| Akmal Alimov | Financial Analysis | Sevara Aliyeva | 58 | failed |
| Akmal Alimov | Financial Analysis | Sevara Aliyeva | 71 | completed |
| Akmal Alimov | Java Basics | Sardor Qodirov | 71 | completed |
| Akmal Alimov | Java Basics | Dilshod Karimov | 85 | completed |
| Akmal Alimov | Linear Algebra | Kamola Ergasheva | 56 | failed |
| Akmal Alimov | Linear Algebra | Zulfiya Saidova | 78 | completed |
| Akmal Alimov | Linear Algebra | Kamola Ergasheva | 57 | failed |
| Akmal Alimov | Project Management | Sevara Aliyeva | NaN | dropped |
| Akmal Alimov | Python Basics | Sardor Qodirov | 88 | completed |
| Akmal Alimov | Python Basics | Dilshod Karimov | 62 | completed |
| Akmal Alimov | SQL for Analytics | Nodira Alimova | 83 | completed |
| Akmal Alimov | SQL for Analytics | Nodira Alimova | 70 | completed |
| Akmal Alimov | SQL for Analytics | Nodira Alimova | 64 | completed |
| Akmal Alimov | Statistics 101 | Kamola Ergasheva | 72 | completed |
| Akmal Alimov | Statistics 101 | Kamola Ergasheva | 50 | failed |
… 2500 qatordan birinchi 15 tasi
2500 qator
8-natija
| a | b | city |
|---|---|---|
| Shahnoza | Akmal | Bukhara |
| Shahnoza | Aziz | Bukhara |
| Shahnoza | Aziz | Bukhara |
| Shahnoza | Aziz | Bukhara |
| Shahnoza | Aziz | Bukhara |
| Shahnoza | Aziza | Bukhara |
| Shahnoza | Bekzod | Bukhara |
| Shahnoza | Bekzod | Bukhara |
| Shahnoza | Dilnoza | Bukhara |
| Shahnoza | Dilnoza | Bukhara |
| Shahnoza | Gulnora | Bukhara |
| Shahnoza | Gulnora | Bukhara |
| Shahnoza | Gulnora | Bukhara |
| Shahnoza | Jasur | Bukhara |
| Shahnoza | Jasur | Bukhara |
… 6550 qatordan birinchi 15 tasi
6550 qator
13 ms
Intervyu savollari
S: INNER JOIN va LEFT JOIN farqi?
INNER faqat ikkala tomonda mos kelgan row larni qaytaradi. LEFT chap table ning har bir row ini qaytaradi va o'ng tomon mos kelmagan joyda NULL qo'yadi. "Nol" ma'noli javob bo'lgan har qanday holatda LEFT ishlating.
S: LEFT JOIN dan keyin nega COUNT(*) noto'g'ri javob beradi?
Chunki mos kelmagan chap row lar baribir bitta chiqish row i hosil qiladi (o'ng tomoni NULL), COUNT(*) esa row larni sanaydi. Buning o'rniga o'ng table ning NULL bo'lmaydigan column ini sanang: COUNT(e.enrollment_id).
S: LEFT JOIN da shartni ON ga va WHERE ga qo'yish orasida qanday farq bor?
ON o'ng table ni join dan oldin filtrlaydi, shuning uchun mos kelmagan chap row lar saqlanadi. WHERE join dan keyin filtrlaydi, ya'ni NULL bilan to'ldirilgan row larni olib tashlaydi va LEFT JOIN ni amalda INNER JOIN ga aylantiradi.
S: A da bor, B da mos kelmaydigan row larni qanday topasiz?
A LEFT JOIN B ON ... WHERE B.primary_key IS NULL, yoki NOT EXISTS. Column NULL bo'lmasligi kafolatlanmagan bo'lsa, NOT IN dan qoching (3-bob).
S: Self join nima va u qachon kerak?
Table ning ikkita alias ostida o'ziga o'zi join qilinishi — bitta table ichidagi row larni solishtirish uchun: xodim/rahbar iyerarxiyasi, umumiy atributga ega juftliklar, ketma-ket hodisalar. O'z-o'ziga juftlanish va takroriy akslarni to'sish uchun a.id < b.id qo'shing.
S: JOIN qo'shganingizdan keyin SUM ikki barobar oshdi. Nima bo'ldi?
Fan-out: join ko'p tomonda bir nechta row ga mos keldi, bu chap row larni va demak qo'shilayotgan qiymatlarni takrorladi. Yechim — ko'p tomonni avval aggregate qilish (CTE yoki derived table), keyin join qilish; DISTINCT emas.
S: JOIN tartibi natijaga ta'sir qiladimi?
Inner join lar uchun yo'q — ular kommutativ va optimizer ularni erkin qayta tartiblaydi. Outer join lar uchun ha: LEFT JOIN dan keyin qo'yilgan INNER JOIN LEFT JOIN saqlab qolgan NULL li row larni o'chirib yuborishi mumkin.
S: CROSS JOIN nimaga kerak?
Birikmalarning to'liq to'rini yaratish uchun — har bir mahsulot × har bir oy — keyin unga real data ni LEFT JOIN qilasiz, shunda bo'sh birikmalar yo'qolmay 0 bo'lib chiqadi.
Xulosa
- JOIN mos row larni yonma-yon yopishtiradi. JOIN turlari orasidagi yagona farq — mos kelmagan row lar taqdiri.
INNER JOIN= faqat mos kelganlar.LEFT JOIN= barcha chap row lar + mos kelganlar.RIGHT= LEFT ning aksi.FULL= ikkala tomon.CROSS= barcha birikmalar.- Aniq
JOIN ... ONishlating. Vergul join vaNATURAL JOINdan qoching. - LEFT JOIN dan keyin o'ng table column ini sanang, hech qachon
COUNT(*)ni emas — aks holda nol lar birga aylanadi. - Anti-join =
LEFT JOIN ... WHERE right_pk IS NULL— "qaysi X da Y yo'q?" savolining javobi. - ON oldin, WHERE keyin filtrlaydi. O'ng table sharti
WHEREda bo'lsa, LEFT JOIN indamay INNER JOIN ga aylanadi. - Bir marta LEFT ga o'tsangiz, LEFT da qoling — keyingi
INNER JOINuni bekor qiladi. - Fan-out — xavfli xato: ko'p tomonga join qilish row larni takrorlaydi va har bir
SUMvaCOUNTni shishiradi. Row sonini oldin va keyin tekshiring; avval aggregate qiling, keyin join.
Keyingi: 6-bob — subquery va CTE lar, ya'ni bitta query natijasini boshqasiga kirish sifatida ishlatish vositalari.
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.