Asosiy qismga o'tish

JOIN lar

5-bob 12 kod bloki 4141 so'z

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.

📌 Fikrlash modeli

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.

sql9 qator
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_namelast_namegradestatus
RustamNazarov88completed
SardorKarimovNaNactive
GulnoraYusupova75completed
SardorKarimovNaNactive
KamolaUmarovaNaNactive

5 qator

1 ms

💡 JOIN ni qanday yozish kerak — har safar
  1. Menga kerak column lar qaysi table larda?
  2. Ularning umumiy column i qaysi? (Foreign key larga qarang.)
  3. Qaysi table "ko'p" tomon? FROM ni o'shandan boshlang.
  4. Mos kelmagan row lar saqlanishi kerakmi? Ha bo'lsa → LEFT JOIN. Yo'q bo'lsa → INNER JOIN.

ON, USING va eski vergul sintaksisi

python12 qator
-- 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_namegrade
Rustam88
SardorNaN
Gulnora75
SardorNaN
KamolaNaN
Ulug'bek83
MalikaNaN
Sevara77
Dilnoza63
SevaraNaN
Otabek67
Kamola62
Gulnora77
Zulfiya79
Zulfiya80

… 2500 qatordan birinchi 15 tasi

2500 qator

2-natija

first_namegrade
Rustam88
SardorNaN
Gulnora75
SardorNaN
KamolaNaN
Ulug'bek83
MalikaNaN
Sevara77
Dilnoza63
SevaraNaN
Otabek67
Kamola62
Gulnora77
Zulfiya79
Zulfiya80

… 2500 qatordan birinchi 15 tasi

2500 qator

3-natija

first_namegrade
Rustam88
SardorNaN
Gulnora75
SardorNaN
KamolaNaN
Ulug'bek83
MalikaNaN
Sevara77
Dilnoza63
SevaraNaN
Otabek67
Kamola62
Gulnora77
Zulfiya79
Zulfiya80

… 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. :::

⚠️ `NATURAL JOIN` — hech qachon ishlatmang

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:

sql8 qator
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;
titleenrollmentsavg_grade
Linear Algebra20068.3
Python Basics19379.2
Financial Analysis18974.7
Probability18865.6
Java Basics18773.9
SQL for Analytics18674.3
Graphic Design17973.5
Statistics 10117463.6
Web Development17475.2
Project Management17075.1
Data Visualization16774.2
Machine Learning16769.4
Excel for Business16579.9
UX Design16176.1
Deep Learning0NaN

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.

⚠️ `COUNT(*)` 0 emas, 1 yozgan bo'lardi

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:

sql6 qator
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_idteacher
18Zulfiya Saidova
19Malika Umarova
20Malika 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.

INNER JOIN faqat ikkalasida mos row lar LEFT JOIN chap row lar + mos kelganlar RIGHT JOIN o'ng row lar + mos kelganlar FULL OUTER JOIN ikkala tomondan hammasi LEFT ANTI-JOIN LEFT JOIN + WHERE o'ng IS NULL CROSS JOIN har bir row × har bir row m × n row — shartsiz
⚠️ SQLite da 3.39 versiyagacha RIGHT va FULL JOIN yo'q

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.

sql4 qator
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_idtitle
12Deep Learning

1 qator

1 ms

python12 qator
-- (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.

sql12 qator
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;
studentcourseteachergradestatus
Rustam NazarovWeb DevelopmentDilshod Karimov88completed
Sardor KarimovMachine LearningJasur ToshevNaNactive
Gulnora YusupovaStatistics 101Kamola Ergasheva75completed
Sardor KarimovSQL for AnalyticsNodira AlimovaNaNactive
Kamola UmarovaData Visualization(yo'q)NaNactive
Ulug'bek QodirovExcel for BusinessSevara Aliyeva83completed

6 qator

1 ms

⚠️ LEFT JOIN dan keyingi INNER JOIN LEFT ni bekor qiladi

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.

python9 qator
-- 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_astudent_bcity
DilnozaAkmalAndijan
DilnozaAkmalAndijan
DilnozaAzizaAndijan
DilnozaAzizaAndijan
DilnozaDostonAndijan
DilnozaDostonAndijan
DilnozaGulnoraAndijan
DilnozaJasurAndijan
DilnozaJasurAndijan
DilnozaKamolaAndijan
DilnozaKamolaAndijan
DilnozaKamolaAndijan
DilnozaMalikaAndijan
DilnozaOtabekAndijan
DilnozaOtabekAndijan

… 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.

💡 Nega `<`, `<>` emas

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.

sql7 qator
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:

python8 qator
-- 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.

⚠️ Fan-out ni qanday aniqlash va tuzatish
  • 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);
  • DISTINCT bilan "tuzatmang". SUM(DISTINCT salary) tasodifan bir xil oylik oladigan ikkita teacher ni bittaga qo'shib yuboradi. DISTINCT alomatni 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.

python16 qator
-- (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

titlecompleted
Python Basics130
SQL for Analytics134
Statistics 10181
Data Visualization111
Machine Learning110
Web Development114
Excel for Business120
Project Management118
UX Design112
Graphic Design139
Linear Algebra116
Deep Learning0
Java Basics123
Financial Analysis125
Probability101

15 qator

2-natija

titlecompleted
Python Basics130
SQL for Analytics134
Statistics 10181
Data Visualization111
Machine Learning110
Web Development114
Excel for Business120
Project Management118
UX Design112
Graphic Design139
Linear Algebra116
Java Basics123
Financial Analysis125
Probability101

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

python46 qator
-- 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_namecourses
Zulfiya19
Shohrux17
Sardor16
Gulnora16
Otabek15
Shohrux15
Aziz15
Nilufar15
Gulnora15
Shahnoza15
Malika14
Zulfiya14
Akmal14
Kamola14
Kamola14

… 300 qatordan birinchi 15 tasi

300 qator

2-natija

full_namesubjectlessons
Kamola ErgashevaStatistics286
Sardor QodirovProgramming276
Sevara AliyevaBusiness273
Dilshod KarimovProgramming260
Nodira AlimovaData Science258
Zulfiya SaidovaStatistics256
Jasur ToshevData Science251
Otabek RahimovBusiness241
Gulnora YusupovaDesign168
Malika UmarovaDesign164
Rustam HalilovDatabases0
Akmal NazarovDatabases0

12 qator

3-natija

first_namelast_namegrade
GulnoraQodirova96
ZulfiyaYusupova95
KamolaTosheva94
Ulug'bekYusupov92
RustamSaidov91
ShahnozaRahimova91
DostonRahimov90
ShohruxUmarov90
ShohruxAlimov90
KamolaErgasheva90
KamolaKarimova90
GulnoraErgasheva89
OtabekSaidov89
OtabekUmarov88
AzizaNazarova88

… 186 qatordan birinchi 15 tasi

186 qator

4-natija

title
Deep Learning

1 qator

5-natija

categoryenrollmentsrevenue
Business524720 000 000
Math562683 800 000
Programming554646 750 000
Data520541 250 000
Design340306 900 000

5 qator

6-natija

citygradedavg_grade
Samarkand23376.7
Nukus15473.2
Namangan17373.1
Karshi15473.1
Andijan13472.8
Bukhara23872.2
Tashkent49572
Fergana20871.9
(unknown)3771.8

9 qator

7-natija

studentcourseteachergradestatus
Akmal AlimovFinancial AnalysisSevara Aliyeva58failed
Akmal AlimovFinancial AnalysisSevara Aliyeva71completed
Akmal AlimovJava BasicsSardor Qodirov71completed
Akmal AlimovJava BasicsDilshod Karimov85completed
Akmal AlimovLinear AlgebraKamola Ergasheva56failed
Akmal AlimovLinear AlgebraZulfiya Saidova78completed
Akmal AlimovLinear AlgebraKamola Ergasheva57failed
Akmal AlimovProject ManagementSevara AliyevaNaNdropped
Akmal AlimovPython BasicsSardor Qodirov88completed
Akmal AlimovPython BasicsDilshod Karimov62completed
Akmal AlimovSQL for AnalyticsNodira Alimova83completed
Akmal AlimovSQL for AnalyticsNodira Alimova70completed
Akmal AlimovSQL for AnalyticsNodira Alimova64completed
Akmal AlimovStatistics 101Kamola Ergasheva72completed
Akmal AlimovStatistics 101Kamola Ergasheva50failed

… 2500 qatordan birinchi 15 tasi

2500 qator

8-natija

abcity
ShahnozaAkmalBukhara
ShahnozaAzizBukhara
ShahnozaAzizBukhara
ShahnozaAzizBukhara
ShahnozaAzizBukhara
ShahnozaAzizaBukhara
ShahnozaBekzodBukhara
ShahnozaBekzodBukhara
ShahnozaDilnozaBukhara
ShahnozaDilnozaBukhara
ShahnozaGulnoraBukhara
ShahnozaGulnoraBukhara
ShahnozaGulnoraBukhara
ShahnozaJasurBukhara
ShahnozaJasurBukhara

… 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 ... ON ishlating. Vergul join va NATURAL JOIN dan 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 WHERE da bo'lsa, LEFT JOIN indamay INNER JOIN ga aylanadi.
  • Bir marta LEFT ga o'tsangiz, LEFT da qoling — keyingi INNER JOIN uni bekor qiladi.
  • Fan-out — xavfli xato: ko'p tomonga join qilish row larni takrorlaydi va har bir SUM va COUNT ni 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.

Telegramda yozish Narxlar