SQL Asoslari
Amaliyotdagi analyst ishlatadigan deyarli har qanday dataset CSV faylda emas, database ichida turadi. Savdo, foydalanuvchilar, buyurtmalar, imtihon natijalari, sensor ko'rsatkichlari — kompaniya bularni table larda saqlaydi va sizga fayl emas, connection beradi. Shuning uchun data analytics kursida SQL pandas dan oldin keladi: pandas faqat sizda allaqachon bor data ni tahlil qila oladi, SQL esa o'sha data ni olib beradi.
Bu bobda asosiy atamalar — table, row, column, key, NULL, dialect — o'rganiladi va 2–13-boblardagi barcha query lar ishlaydigan kichik database tuziladi. Shoshilmang: SQL da keyinroq chalkash tuyuladigan narsalarning deyarli hammasi shu sahifadagi g'oyalardan kelib chiqadi.
SQL nima?
SQL — Structured Query Language. Bu relational database bilan gaplashish tili: unga savol berish va u saqlayotgan ma'lumotni o'zgartirish uchun ishlatiladi.
SQL ning eng muhim xususiyati — u declarative til. Python da siz qanday qilib bajarishni qadam-baqadam yozasiz. SQL da esa nima kerakligini yozasiz, qanday olishni database ning o'zi hal qiladi.
| Python (imperative — qanday) | SQL (declarative — nima) |
|---|---|
result = [] for s in students: if s.city == 'Tashkent': result.append(s.name) |
SELECT first_name FROM students WHERE city = 'Tashkent'; |
Imperative — taksi haydovchisiga har bir burilishni aytish: "shu yerdan chapga, endi to'g'ri, svetoforda o'ngga". Declarative — "meni aeroportga olib boring" deyish, yo'lni haydovchining o'zi tanlaydi. SQL — ikkinchisi, va database ning query planner i eng tez yo'lni tanlaydigan haydovchi.
Buning talabalar uchun amaliy natijasi bor: butunlay boshqacha yozilgan ikkita SQL query bir xil natijani bir xil tezlikda berishi mumkin, chunki database ularni ichkarida qayta yozadi. Shuningdek, query sekin ishlayotganda odatda uni qayta yozib emas, planner ga yaxshiroq vosita berib tuzatasiz — bu index (11-bob).
SQL, database va DBMS — farqi
Talabalar bu uchta so'zni doim aralashtiradi. Bir marta aniq ajratib bering:
| Atama | Aslida nima | Misol |
|---|---|---|
| Database | Saqlanayotgan ma'lumotning o'zi — table lar va ularning ichidagi data | school.db |
| DBMS / RDBMS | O'sha ma'lumotni saqlaydigan, himoyalaydigan va qidiradigan dastur | PostgreSQL, MySQL, SQLite |
| SQL | O'sha dasturga buyruq berish uchun ishlatiladigan til | SELECT * FROM students; |
RDBMS dagi "R" — relational, ya'ni bog'langan degani: data bir nechta table ga bo'linadi va ular umumiy key column lar orqali bir-biriga bog'langan bo'ladi. 5-bob (JOIN lar) to'liq shu bog'langan table larni qayta birlashtirishga bag'ishlangan.
Nega analyst SQL ni bilishi shart
Talabalarga birinchi kuni aytishga arziydigan to'rtta halol sabab:
- Data o'sha yerda. Real kompaniya data si Postgres/MySQL/BigQuery da turadi. SQL bilmaslik — kimdir sizga CSV eksport qilib berishini kutish demak.
- Manbada filtrlash ancha tez. 50 million row ni pandas ga tortsangiz, RAM tugaydi.
WHERE year = 2026esa database ga 200 000 row qaytarish imkonini beradi — og'ir ishni data egasi bo'lgan mashina bajaradi. - Bu sohadagi eng universal ko'nikma. Analyst, data engineer, backend developer, BI mutaxassisi va ML engineer — hammasi ishlatadi. Library lar bir necha yilda almashadi, 1990-yildagi SQL esa hali ham ishlaydi.
- Intervyuda so'raladi. Data analytics intervyusida deyarli doim jonli SQL topshirig'i bo'ladi — odatda JOIN va GROUP BY, ko'pincha window function ham.
Filtrlash va aggregation ni SQL da, vizualizatsiya va model ni Python da qiling. pandas ga iloji boricha eng kichik table ni olib kiring. Aynan shu odat production data bilan ishlay oladigan analyst ni ishlay olmaydiganidan ajratib turadi.
Table, row, column, key lar
Table (uni relation ham deyishadi) tashqi ko'rinishidan xuddi Excel jadvaliga o'xshaydi, lekin ikkita qat'iy qo'shimcha qoidasi bor.
Excel da bo'lmagan ikkita qat'iy qoida:
- Har bir column ning bitta qat'iy data type i bor.
INTEGERdeb e'lon qilingan column 500-row da to'satdan"noma'lum"ni saqlay olmaydi. Excel da odamlar buni doim qiladi, va aynan shuning uchun Excel data sini tahlil qilish juda azob. - Row larning tartibi yo'q. Bu hammani hayron qoldiradi. Table — row lar to'plami; database ularni xohlagan tartibda qaytarishi mumkin. Aniq tartib kerak bo'lsa, albatta
ORDER BYyozishingiz kerak. O'tgan safar ko'rgan tartibingizga hech qachon ishonmang.
Primary key (PK)
Primary key — har bir row ni yagona qilib aniqlaydigan column (yoki column lar birikmasi). U unique bo'lishi va hech qachon NULL bo'lmasligi shart. Bitta table da faqat bitta primary key bo'ladi.
Talabalardan so'rang: first_name students table ining primary key i bo'la oladimi? Yo'q — ikkita student ham Aziza bo'lishi mumkin. phone_number chi? Xavfli — odamlar raqamini almashtiradi va row ning identifikatori ham o'zgarib ketadi. Shuning uchun ma'nosi yo'q, avtomatik o'sadigan student_id ishlatiladi: u hech qanday biznes ma'no tashimaydi, demak real hayotdagi hech narsa uni o'zgartirishga majbur qila olmaydi.
Foreign key (FK)
Foreign key — boshqa table ning primary key iga ishora qiluvchi column. Relational database dagi haqiqiy "bog'lanish" aynan shu.
Foreign key bir vaqtning o'zida ikkita vazifani bajaradi:
- Sizga (va query planner ga) table larni qanday JOIN qilishni ko'rsatadi.
- Database ga noto'g'ri data ni rad etishni buyuradi. Agar
student_id = 999uchun enrollment qo'shmoqchi bo'lsangiz va bunday student mavjud bo'lmasa, insert bajarilmaydi. Bu referential integrity deyiladi, va aynan shu tufayli database lar Excel jadvallariga qaraganda ancha toza bo'ladi.
Chunki data ning buzilishi aynan takrorlanishdan boshlanadi. Agar har bir enrollment row ida student ning to'liq ismi va shahri ham saqlansa, boshqa shaharga ko'chgan student uchun yuzlab row ni yangilash kerak bo'ladi — va bitta yangilash o'tkazib yuborilsa, database ning o'zi o'zi bilan zid bo'lib qoladi. Har bir faktni aynan bir marta saqlash normalization deyiladi (10-bob). JOIN — buning uchun to'laydigan narximiz, va bu foydali kelishuv.
Data types
Har bir column type bilan e'lon qilinadi. Type lar database ga qarab biroz farq qiladi, lekin quyidagilar analytics ishining 95% ini qoplaydi:
| Type | Nimani saqlaydi | Misol | Talaba uchun izoh |
|---|---|---|---|
INTEGER |
Butun sonlar | 42, -7 |
ID lar, sanoq, yosh |
REAL / FLOAT / DOUBLE |
Kasrli sonlar | 3.14, 85.5 |
Pul uchun hech qachon ishlatmang — yaxlitlash xatosi bor |
DECIMAL(10,2) / NUMERIC |
Aniq kasrli sonlar | 1250.00 |
Pul uchun aynan shu type |
TEXT / VARCHAR(n) |
Matn (string) | 'Tashkent' |
VARCHAR(50) = ko'pi bilan 50 ta belgi |
DATE |
Sana | '2026-03-12' |
Doim YYYY-MM-DD formatida |
TIMESTAMP / DATETIME |
Sana + vaqt | '2026-03-12 14:30:00' |
Hodisalar, log lar, buyurtmalar uchun |
BOOLEAN |
TRUE / FALSE | TRUE |
SQLite da haqiqiy BOOLEAN yo'q — 0/1 saqlaydi |
FLOAT ikkilik floating point, shuning uchun 0.1 + 0.2 aniq 0.3 ga teng emas. Million tranzaksiyada bu mayda xatolar yig'ilib, moliyaviy hisobotda ko'zga ko'rinadigan real farqqa aylanadi. DECIMAL(10,2) ishlating — yoki summani eng kichik birlikda (tiyin) INTEGER sifatida saqlang.
Agar sana column i TEXT bo'lib, '12/03/2026' ni saqlasa, WHERE date > '01/01/2026' ularni xronologik emas, alifbo bo'yicha solishtiradi va bema'ni natija beradi. Sanani haqiqiy DATE type da saqlang; matn ishlatish shart bo'lsa, 'YYYY-MM-DD' formatidan foydalaning, chunki bu format matn sifatida ham to'g'ri saralanadi. SQLite aynan shunday qiladi.
NULL — uchinchi qiymat
NULL — SQL dagi eng noto'g'ri tushuniladigan narsa, shuning uchun uni erta va ataylab tushuntiring.
NULL — nol emas. NULL — bo'sh matn ham emas. NULL "biz bilmaymiz" degani. Bu qiymatning yo'qligi.
| Qiymat | Ma'nosi |
|---|---|
0 |
Qiymatni bilamiz, u nolga teng. (Student 0 ball oldi.) |
'' |
Qiymatni bilamiz, u bo'sh matn. |
NULL |
Qiymat nima ekanini umuman bilmaymiz. (Student hali baholanmagan.) |
Buning natijasi — uch qiymatli mantiq (three-valued logic). NULL bilan qilingan har qanday solishtirish TRUE ham, FALSE ham emas — u UNKNOWN qaytaradi, WHERE esa faqat TRUE bo'lgan row larni qoldiradi.
Shuning uchun bu query baholanmagan student lar bor bo'lsa ham nol row qaytaradi:
-- NOTO'G'RI: hech qachon hech narsa qaytarmaydi SELECT * FROM enrollments WHERE grade = NULL; -- TO'G'RI: yagona yo'l — IS NULL / IS NOT NULL SELECT * FROM enrollments WHERE grade IS NULL; SELECT * FROM enrollments WHERE grade IS NOT NULL;
1-natija
| enrollment_id | student_id | course_id | teacher_id | enrolled_at | grade | status |
|---|
0 qator
2-natija
| enrollment_id | student_id | course_id | teacher_id | enrolled_at | grade | status |
|---|---|---|---|---|---|---|
| 2 | 281 | 5 | 11 | 2025-02-12 | None | active |
| 4 | 241 | 2 | 1 | 2025-09-08 | None | active |
| 5 | 211 | 4 | NaN | 2025-09-01 | None | active |
| 7 | 216 | 11 | 3 | 2025-02-05 | None | active |
| 10 | 190 | 2 | 1 | 2025-09-06 | None | active |
| 22 | 74 | 1 | 4 | 2025-09-21 | None | active |
| 23 | 98 | 6 | NaN | 2025-09-16 | None | active |
| 24 | 271 | 13 | 4 | 2025-02-07 | None | active |
| 25 | 120 | 13 | 5 | 2025-09-09 | None | active |
| 27 | 243 | 6 | 4 | 2025-02-11 | None | active |
| 31 | 177 | 7 | 9 | 2025-03-10 | None | active |
| 32 | 106 | 2 | 1 | 2025-09-06 | None | dropped |
| 40 | 191 | 2 | 11 | 2025-02-14 | None | active |
| 41 | 104 | 5 | 11 | 2025-02-22 | None | active |
| 42 | 192 | 9 | 10 | 2025-03-14 | None | active |
… 674 qatordan birinchi 15 tasi
674 qator
3-natija
| enrollment_id | student_id | course_id | teacher_id | enrolled_at | grade | status |
|---|---|---|---|---|---|---|
| 1 | 21 | 6 | 5 | 2025-02-18 | 88 | completed |
| 3 | 85 | 3 | 3 | 2025-02-10 | 75 | completed |
| 6 | 130 | 7 | 12 | 2025-02-19 | 83 | completed |
| 8 | 215 | 9 | 6 | 2025-09-14 | 77 | completed |
| 9 | 102 | 10 | 6 | 2025-10-01 | 63 | completed |
| 11 | 95 | 15 | 8 | 2025-02-27 | 67 | completed |
| 12 | 59 | 1 | 4 | 2025-02-26 | 62 | completed |
| 13 | 221 | 13 | 5 | 2025-02-13 | 77 | completed |
| 14 | 171 | 9 | 6 | 2025-09-14 | 79 | completed |
| 15 | 116 | 3 | 8 | 2025-02-25 | 80 | completed |
| 16 | 49 | 5 | 1 | 2025-09-17 | 61 | completed |
| 17 | 75 | 15 | 8 | 2025-09-27 | 52 | failed |
| 18 | 280 | 3 | 8 | 2025-09-08 | 70 | completed |
| 19 | 189 | 10 | 10 | 2025-02-14 | 92 | completed |
| 20 | 274 | 10 | 10 | 2025-09-10 | 55 | failed |
… 1826 qatordan birinchi 15 tasi
1826 qator
5 ms
:::tip 💡 Darsda aytiladigan jumla
"NULL — qiymat emas, u qiymat turishi kerak bo'lgan bo'shliq. Bo'shliqni hech narsa bilan solishtira olmaysiz, faqat u bor-yo'qligini so'rashingiz mumkin." Talabalar buni yodda saqlaydi. NULL ga 3-bobda batafsil qaytamiz, 4-bobda esa aynan shu sabab COUNT(*) va COUNT(column) har xil natija berishini ko'ramiz.
:::
DDL / DML / DQL / DCL / TCL
SQL buyruqlari beshta oilaga bo'linadi. Talabalar qisqartmalarni yodlashi shart emas, lekin qaysi buyruqlar xavfli ekanini bilishi shart.
| Oila | To'liq nomi | Buyruqlar | Nimaga tegadi |
|---|---|---|---|
| DQL | Data Query Language | SELECT |
Faqat o'qiydi — analyst ishining 90% i |
| DML | Data Manipulation Language | INSERT, UPDATE, DELETE |
Table ichidagi data ni o'zgartiradi |
| DDL | Data Definition Language | CREATE, ALTER, DROP, TRUNCATE |
Tuzilma ni — table larning o'zini o'zgartiradi |
| DCL | Data Control Language | GRANT, REVOKE |
Kimga nima qilishga ruxsat berilgani |
| TCL | Transaction Control Language | COMMIT, ROLLBACK, SAVEPOINT |
O'zgarishlar guruhini tasdiqlash yoki bekor qilish |
WHERE siz yozilgan DELETE FROM students; barcha student larni o'chiradi. WHERE siz UPDATE students SET city = 'Tashkent'; esa hammani Toshkentga "ko'chiradi". Odatni hozirdan shakllantiring: UPDATE yoki DELETE ni yozishdan oldin WHERE ni yozing — yoki yanada xavfsizi: avval uni SELECT sifatida ishga tushiring, row larni ko'ring, va faqat shundan keyin SELECT * ni DELETE ga almashtiring.
SQL dialect lari (SQLite, PostgreSQL, MySQL)
Rasmiy ANSI SQL standarti bor, keyin esa har bir database o'z qo'shimchalarini qo'shadi. Asosiy qismi — SELECT, WHERE, JOIN, GROUP BY, window function lar — hamma joyda bir xil. Farqlar string function lar, date function lar va row larni cheklash usulida ko'rinadi.
| Vazifa | SQLite | PostgreSQL | MySQL | SQL Server |
|---|---|---|---|---|
| Row larni cheklash | LIMIT 10 |
LIMIT 10 |
LIMIT 10 |
TOP 10 |
| String larni birlashtirish | || |
|| |
CONCAT() |
+ |
| Bugungi sana | DATE('now') |
CURRENT_DATE |
CURDATE() |
GETDATE() |
| Avtomatik ID | INTEGER PRIMARY KEY |
SERIAL |
AUTO_INCREMENT |
IDENTITY |
| NULL bilan ishlash | IFNULL() |
COALESCE() |
IFNULL() |
ISNULL() |
COALESCE() ularning hammasida ishlaydi, shuning uchun uni afzal ko'ring — bu qo'llanmada hamma joyda o'shani ishlatamiz.
Bu qo'llanma SQLite dan foydalanadi, sababi juda amaliy: unga server ham, o'rnatish ham, parol ham kerak emas. Database — bitta fayl, Python esa sqlite3 bilan birga keladi. O'rgangan hamma narsangiz to'g'ridan-to'g'ri boshqa database larga o'tadi; dialect muhim farq qilgan joyda izoh beriladi.
Bizning sample database
2–13-boblardagi har bir query aynan shu database ustida ishlaydi. U javoblarni qo'lda tekshirsa bo'ladigan darajada kichik, lekin har xil JOIN, aggregation va window function ni ko'rsata oladigan darajada boy tuzilgan.
Bitta student ko'p course oladi. Bitta course da ko'p student bo'ladi. Buni ikkala tomonning birortasidagi bitta foreign key bilan ifodalab bo'lmaydi — shuning uchun o'rtada uchinchi table yaratiladi va uning row lari juftliklar bo'ladi. enrollments ning har bir row i "bu student shu course da, shu teacher bilan, shu bahoni oldi" deydi. Bu pattern (junction / bridge table) har qanday real database da uchraydi: orders↔products, users↔roles, actors↔films.
To'liq setup script
Buni school_setup.sql nomi bilan saqlang yoki to'g'ridan-to'g'ri SQL dasturingizga qo'ying. U to'rtta table ni yaratadi va data bilan to'ldiradi.
-- ============================================ -- school.db — bu qo'llanma uchun sample database -- ============================================ DROP TABLE IF EXISTS enrollments; DROP TABLE IF EXISTS students; DROP TABLE IF EXISTS courses; DROP TABLE IF EXISTS teachers; CREATE TABLE students ( student_id INTEGER PRIMARY KEY, first_name TEXT NOT NULL, last_name TEXT NOT NULL, gender TEXT CHECK (gender IN ('M','F')), city TEXT, birth_date DATE, enrolled_date DATE NOT NULL ); CREATE TABLE teachers ( teacher_id INTEGER PRIMARY KEY, full_name TEXT NOT NULL, subject TEXT, hired_date DATE, salary DECIMAL(10,2) ); CREATE TABLE courses ( course_id INTEGER PRIMARY KEY, title TEXT NOT NULL, category TEXT, credits INTEGER DEFAULT 3, price DECIMAL(10,2) ); CREATE TABLE enrollments ( enrollment_id INTEGER PRIMARY KEY, student_id INTEGER NOT NULL, course_id INTEGER NOT NULL, teacher_id INTEGER, enrolled_at DATE NOT NULL, grade INTEGER, -- NULL = hali baholanmagan status TEXT DEFAULT 'active', FOREIGN KEY (student_id) REFERENCES students(student_id), FOREIGN KEY (course_id) REFERENCES courses(course_id), FOREIGN KEY (teacher_id) REFERENCES teachers(teacher_id) );
Ma'lumot qayerdan keladi
Bu data qo'lda yozilmagan. datasets/generate.py school.db ni qat'iy seed bilan quradi —
kim ishga tushirsa ham aynan bir xil data chiqadi. Qo'llanmadagi har bir raqam o'sha
fayldan so'rov orqali olingan, muallifning tasavvuridan emas.
import pandas as pd, sqlite3 con = sqlite3.connect(DB) show(pd.read_sql_query(""" SELECT 'students' AS jadval, COUNT(*) AS qator FROM students UNION ALL SELECT 'teachers', COUNT(*) FROM teachers UNION ALL SELECT 'courses', COUNT(*) FROM courses UNION ALL SELECT 'enrollments', COUNT(*) FROM enrollments """, con))
| jadval | qator |
|---|---|
| students | 300 |
| teachers | 12 |
| courses | 15 |
| enrollments | 2 500 |
Endi row larning o'ziga qaraymiz:
SELECT student_id, first_name, last_name, gender, city, enrolled_date FROM students ORDER BY student_id LIMIT 8;
| student_id | first_name | last_name | gender | city | enrolled_date |
|---|---|---|---|---|---|
| 1 | Shahnoza | Alimova | F | Bukhara | 2025-09-03 |
| 2 | Doston | Umarov | M | Fergana | 2025-02-13 |
| 3 | Zulfiya | Yusupova | F | Samarkand | 2025-02-13 |
| 4 | Kamola | Karimova | F | Samarkand | 2025-02-05 |
| 5 | Gulnora | Saidova | F | Namangan | 2025-09-07 |
| 6 | Bekzod | Yusupov | M | Samarkand | 2025-09-07 |
| 7 | Doston | Alimov | M | Karshi | 2025-09-10 |
| 8 | Madina | Rahimova | F | Tashkent | 2025-02-09 |
8 qator
1 ms
:::tip 💡 Nega data aynan shunday tuzilgan Generator ataylab o'quv tuzoqlarini qo'yadi — toza ertak o'rniga haqiqiy xatti-harakat ko'rinsin. Har biri qo'llanmaning keyingi boblarida so'rov bilan tekshiriladi:
- 8 ta student da
city = NULL— shuning uchunCOUNT(city)vaCOUNT(*)har xil natija beradi,WHERE city <> 'Tashkent'esa ularni indamay tashlab ketadi. - "Deep Learning" course da umuman enrollment yo'q — uni hisobotda ko'rishning yagona
yo'li
LEFT JOIN. - 674 ta grade NULL (hali o'qiyapti yoki tashlab ketgan) —
AVG(grade)ularni hisobga olmaydi; bu odatda to'g'ri, lekin tushuntirilishi shart. - 67 ta enrollment da
teacher_id = NULL— teacher hali biriktirilmagan; yana bitta LEFT JOIN holati. - To'rtta status (
completed,active,dropped,failed) —GROUP BYvaCASE WHENuchun ideal. - Bitta teacher da tashlab ketish boshqalardan ancha ko'p — kimligini 5-bobda topasiz. :::
Bu query larni qanday ishga tushirish
Uchta variant, eng osonidan eng professionaligacha. Butun qo'llanma uchun ulardan bittasi yetarli.
1-variant — DB Browser for SQLite (dars uchun eng qulayi)
Bepul grafik dastur (sqlitebrowser.org). Talabalar table larni ko'radi, data ni bosib ko'zdan kechiradi va "Execute SQL" tab ida query yozadi. Dasturning o'zidan boshqa hech narsa o'rnatish shart emas va boshlovchilarni qo'rqitadigan command line yo'q.
- New Database →
school.dbnomi bilan saqlang → "create table" oynasini yoping. - Execute SQL tab iga o'ting, setup script ni qo'ying, Ctrl+Return bosing.
- Write Changes ni bosing (aynan shu qadamni hamma unutadi).
2-variant — sqlite3 command line
`sqlite3 school.db < school_setup.sql # database ni tuzish sqlite3 school.db # sessiyani ochish
sqlite> .headers on
sqlite> .mode column
sqlite> SELECT * FROM students LIMIT 3;
sqlite> .tables
sqlite> .schema students
sqlite> .quit:::tip 💡 Doim avval shu ikkitasini yozing.headers onva.mode column` o'qib bo'lmaydigan, vertikal chiziq bilan ajratilgan natijani column nomlari bor normal jadvalga aylantiradi. Ularsiz talabalar qaysi column qaysi ekanini ajrata olmaydi.
:::
3-variant — Python (12-bobda shunga boramiz)
import sqlite3 import pandas as pd # connection: oddiy fayl, server ham, parol ham kerak emas conn = sqlite3.connect("school.db") # database ni setup script dan bir marta tuzamiz with open("school_setup.sql", "r", encoding="utf-8") as f: conn.executescript(f.read()) # endi har qanday query DataFrame bo'lib qaytadi df = pd.read_sql("SELECT * FROM students;", conn) print(df.head()) conn.close()
Bu — qo'llanmaning ikki yarmi orasidagi ko'prik: SQL data ni olib keladi, shu yerdan esa Seaborn uni chizadi.
Birinchi query ingiz
Eng kichik foydali SQL ifodasi:
SELECT * FROM students;
Uni ovoz chiqarib, o'ngdan chapga uchta bo'lakda o'qing:
FROM students— qaysi table ga qarash kerak.SELECT *— qaysi column larni ko'rsatish kerak;*hammasi degani.;— ifoda tugadi. Ba'zi dasturlar nuqta-vergulsiz ham ishlaydi; baribir talabalarni odatlantiring, chunki ikkita ifodani birga yozishlari bilan u majburiy bo'lib qoladi.
Endi orqasida haqiqiy savol turgan query — "Toshkentdan qaysi student lar bor, eng yangilari birinchi?":
SELECT first_name, last_name, city, enrolled_date FROM students WHERE city = 'Tashkent' ORDER BY enrolled_date DESC;
| first_name | last_name | city | enrolled_date |
|---|---|---|---|
| Nilufar | Tosheva | Tashkent | 2025-09-21 |
| Bekzod | Rahimov | Tashkent | 2025-09-17 |
| Doston | Umarov | Tashkent | 2025-09-14 |
| Jasur | Toshev | Tashkent | 2025-09-13 |
| Dilnoza | Qodirova | Tashkent | 2025-09-13 |
| Aziz | Qodirov | Tashkent | 2025-09-12 |
| Nilufar | Nazarova | Tashkent | 2025-09-11 |
| Kamola | Karimova | Tashkent | 2025-09-10 |
| Dilnoza | Saidova | Tashkent | 2025-09-10 |
| Nilufar | Yusupova | Tashkent | 2025-09-10 |
| Gulnora | Rahimova | Tashkent | 2025-09-09 |
| Dilnoza | Rahimova | Tashkent | 2025-09-09 |
| Gulnora | Umarova | Tashkent | 2025-09-09 |
| Rustam | Toshev | Tashkent | 2025-09-08 |
| Shohrux | Rahimov | Tashkent | 2025-09-07 |
… 82 qatordan birinchi 15 tasi
82 qator
0 ms
Natija:
| first_name | last_name | city | enrolled_date |
|---|---|---|---|
| Otabek | Nazarov | Tashkent | 2026-02-01 |
| Jasur | Rahimov | Tashkent | 2025-09-15 |
| Aziza | Karimova | Tashkent | 2025-09-01 |
Yozadigan har bir query ga taalluqli qoidalar
- Keyword lar katta-kichik harfga bog'liq emas.
select,SELECTvaSeLeCt— hammasi ishlaydi. Kelishuv: keyword larni KATTA harfda, o'zingiz bergan nomlarni kichik harfda yozing, shunda tuzilma bir qarashda ko'rinadi. - Data esa katta-kichik harfga bog'liq. PostgreSQL da
'Tashkent'va'tashkent'— har xil string. (SQLite ASCII matnniLIKEda farqlamaydi, lekin=da farqlaydi.) Talabalar bunga doim qoqiladi. - String lar bitta qo'shtirnoq bilan.
'Tashkent'. Ikkitali qo'shtirnoq identifier (column yoki table nomi) degani, matn emas — bu uslub emas, real farq. - Bo'sh joy bepul. Har bir clause ni alohida qatorga yozing. Besh qatorli query bir necha soniyada o'qiladi; xuddi shu query bitta qatorda esa o'qilmaydi.
- Izohlar:
-- qator oxirigachayoki/* bir necha qator */.
SELECT * o'rganish paytida yaxshi. Saqlab qo'yadigan har qanday kodda column larni nomlab yozing. Sabablari: kerak bo'lmagan column larni ham uzatadi (sekin), kimdir column qo'shishi yoki tartibini o'zgartirishi bilan indamay buziladi, va query aslida nima haqida ekanini o'quvchidan yashiradi.
Bajarilish tartibi
Bu bitta g'oya talabalarning SQL dagi xatolarini boshqa hamma narsadan ko'ra ko'proq tushuntiradi. SQL siz yozgan tartibda bajarilmaydi.
Talabalar birinchi haftada duch keladigan ikkita qoida aynan shu diagrammadan kelib chiqadi:
1. WHERE alias ni ko'rmaydi, ORDER BY esa ko'radi
-- XATO: 2-qadamda 'age_years' hali mavjud emas, -- chunki uni yaratadigan SELECT — 5-qadam SELECT first_name, (2026 - CAST(strftime('%Y', birth_date) AS INTEGER)) AS age_years FROM students WHERE age_years > 20; -- ISHLAYDI: ORDER BY — 7-qadam, alias allaqachon mavjud SELECT first_name, (2026 - CAST(strftime('%Y', birth_date) AS INTEGER)) AS age_years FROM students ORDER BY age_years DESC;
1-natija
| first_name | age_years |
|---|---|
| Shahnoza | 28 |
| Doston | 27 |
| Zulfiya | 24 |
| Kamola | 24 |
| Gulnora | 28 |
| Bekzod | 24 |
| Doston | 22 |
| Madina | 26 |
| Sardor | 23 |
| Dilnoza | 26 |
| Jasur | 27 |
| Rustam | 25 |
| Bekzod | 24 |
| Otabek | 26 |
| Madina | 25 |
… 300 qatordan birinchi 15 tasi
300 qator
2-natija
| first_name | age_years |
|---|---|
| Shahnoza | 28 |
| Gulnora | 28 |
| Dilnoza | 28 |
| Aziz | 28 |
| Bekzod | 28 |
| Gulnora | 28 |
| Kamola | 28 |
| Otabek | 28 |
| Shohrux | 28 |
| Ulug'bek | 28 |
| Zulfiya | 28 |
| Doston | 28 |
| Doston | 28 |
| Dilnoza | 28 |
| Sardor | 28 |
… 300 qatordan birinchi 15 tasi
300 qator
1 ms
Birinchisini tuzatish uchun yo ifodani WHERE ichida takrorlaysiz, yo query ni subquery yoki CTE ga o'raysiz (6-bob), shunda filtrlash paytida alias allaqachon hisoblangan bo'ladi.
2. WHERE row larni, HAVING guruhlarni filtrlaydi
WHERE 2-qadamda, guruhlashdan oldin ishlaydi — shuning uchun u AVG() yoki COUNT() ni ishlata olmaydi, chunki hali hech qanday guruh yo'q. HAVING esa 4-qadamda, guruhlashdan keyin ishlaydi, shuning uchun ishlata oladi.
-- "Faqat tugatilgan enrollment lar orasida qaysi course larning o'rtachasi 80 dan yuqori?" SELECT course_id, AVG(grade) AS avg_grade FROM enrollments WHERE status = 'completed' -- 2-qadam: alohida ROW larni filtrlaydi GROUP BY course_id -- 3-qadam: guruhlarni yasaydi HAVING AVG(grade) > 80 -- 4-qadam: butun GURUH larni filtrlaydi ORDER BY avg_grade DESC; -- 7-qadam: alias shu yerda mavjud
| course_id | avg_grade |
|---|---|
| 7 | 80.25 |
1 qator
1 ms
:::tip 💡 Talabalarga takrorlatadigan bitta jumla "WHERE guruhlashdan oldin row larni filtrlaydi. HAVING guruhlashdan keyin guruhlarni filtrlaydi." Bu shu tilning eng ko'p so'raladigan intervyu savollaridan biri ham — 4-bobda chuqurroq ko'ramiz. :::
Ko'p uchraydigan xatolar
| Xato | Nima bo'ladi | Yechim |
|---|---|---|
WHERE grade = NULL |
0 ta row qaytaradi, xato xabari ham chiqmaydi | WHERE grade IS NULL |
WHERE city = "Tashkent" |
Ikkitali qo'shtirnoq column nomi degani → "no such column" | Bitta qo'shtirnoq: 'Tashkent' |
| Row lar qat'iy tartibda keladi deb o'ylash | Data o'sishi bilan tartib indamay o'zgaradi | Doim ORDER BY yozing |
WHERE ichida alias ishlatish |
"no such column" — SELECT keyinroq ishlaydi | Ifodani takrorlang yoki CTE ishlating |
WHERE siz DELETE/UPDATE |
Butun table o'zgaradi | Avval SELECT, keyin fe'lni almashtiring |
Pulni FLOAT da saqlash |
Yaxlitlash xatolari yig'iladi | DECIMAL(10,2) |
Sanani '12/03/2026' kabi TEXT da saqlash |
Alifbo bo'yicha saralanadi va solishtiriladi | DATE, yoki matn bo'lsa 'YYYY-MM-DD' |
; ni unutish |
Dastur qo'shimcha kiritishni cheksiz kutadi | Har bir ifodani ; bilan tugating |
Intervyu savollari
S: SQL va MySQL orasidagi farq nima?
SQL — til. MySQL — o'sha tilni tushunadigan va data ni saqlaydigan dastur (RDBMS). PostgreSQL, SQLite va SQL Server — MySQL ning muqobillari, hammasi kichik dialect farqlari bilan SQL da gaplashadi.
S: Primary key nima va u unique key dan nimasi bilan farq qiladi?
Ikkalasi ham unique likni ta'minlaydi. Primary key qo'shimcha ravishda NULL bo'la olmaydi va table da faqat bittasi bo'ladi. Unique key esa (ko'p database larda bir marta) NULL ga ruxsat berishi mumkin va table da bir nechtasi bo'lishi mumkin. Primary key — row ning rasmiy identifikatori.
S: Foreign key nima uchun kerak?
U boshqa table ning primary key iga bog'lanishni saqlaydi va referential integrity ni ta'minlaydi — database mavjud bo'lmagan "ota" ga ishora qiluvchi row ni qo'shishni rad etadi va hali "farzand" lari bor "ota" ni o'chirishga yo'l qo'ymaydi (ON DELETE CASCADE qo'yilmagan bo'lsa).
S: NULL 0 yoki bo'sh string bilan bir xilmi?
Yo'q. 0 va '' — ma'lum qiymatlar. NULL esa noma'lum degani. NULL bilan har qanday solishtirish UNKNOWN beradi, shuning uchun = NULL hech qachon mos kelmaydi; IS NULL ishlating. NULL arifmetikaga ham o'tadi: NULL + 10 — bu NULL.
S: WHERE va HAVING orasidagi farq nima?
WHERE GROUP BY dan oldin alohida row larni filtrlaydi, shuning uchun aggregate function ishlata olmaydi. HAVING GROUP BY dan keyin guruhlarni filtrlaydi, shuning uchun ishlata oladi. Agar GROUP BY bo'lmasa, WHERE ni afzal ko'ring — u row larni ertaroq olib tashlaydi, demak kamroq ish bajariladi.
S: SELECT ifodasi aslida qanday tartibda bajariladi?
FROM/JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT. Aynan shuning uchun SELECT da yaratilgan alias ORDER BY da ishlaydi, WHERE da esa ishlamaydi.
S: DELETE, TRUNCATE va DROP farqi?
DELETE row larni o'chiradi (WHERE bo'lishi mumkin, rollback qilinadi, har bir row log ga yoziladi). TRUNCATE butun table ni tez bo'shatadi, WHERE siz. DROP esa table ning o'zini — tuzilmasi bilan birga — o'chiradi.
S: Nega production kodda SELECT * dan qochish kerak?
U tarmoq orqali keraksiz data ni uzatadi, ba'zi index optimizatsiyalarini to'sadi va table column lari o'zgarganda indamay buziladi. Column larni nomlab yozish query ning maqsadini ham hujjatlashtiradi.
Xulosa
- SQL — declarative til: siz kerakli natijani tasvirlaysiz, uni qanday olishni database tanlaydi.
- Table = row lar (yozuvlar) × column lar (type ga ega atributlar). Row larning o'z tartibi yo'q — tartib kerak bo'lsa,
ORDER BYyozing. - Primary key = unique, hech qachon NULL emas, table da bitta. Foreign key = boshqa table ning PK iga ishora; bu relational dagi "bog'lanish" va u data sifatini himoya qiladi.
- NULL "noma'lum" degani, nol emas.
=bilan emas,IS NULL/IS NOT NULLbilan solishtiring. - Pul uchun
DECIMAL, sana uchun haqiqiyDATEtype (yoki'YYYY-MM-DD'matn) ishlating. - Bajarilish tartibi: FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT. Bu alias larni ham,
WHEREvaHAVINGfarqini ham tushuntiradi. - Bizning
school.db—students,teachers,courses,enrollments— ataylab qo'yilgan NULL lar va bitta bo'sh course ni o'z ichiga oladi, shunda keyingi boblar ideallashtirilgan misol emas, real xatti-harakatni ko'rsata oladi.
Keyingi: 2-bob SELECT ni to'liq ochib beradi — column ifodalari, alias lar, WHERE, ORDER BY, LIMIT, DISTINCT.
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.