String, date va CASE WHEN
Real data iflos bo'ladi. Ismlarda ortiqcha bo'sh joylar bor, sanalar matn ko'rinishida keladi, kategoriyalarni raqamlardan chiqarish kerak. Bu bob — shularning hammasini query ichida, data pandas ga yetib borishidan oldin tuzatish uchun asboblar to'plami.
CASE WHEN birinchi keladi, chunki u bu yerdagi eng foydali konstruksiya — u SQL ning if / elif / else i.
CASE WHEN
CASE shartlarini yuqoridan pastga tekshiradi va TRUE bo'lgan birinchi shartning qiymatini qaytaradi. Hech biri mos kelmasa, ELSE qiymatini — ELSE yo'q bo'lsa NULL ni qaytaradi.
SELECT enrollment_id, grade, CASE WHEN grade IS NULL THEN 'baholanmagan' WHEN grade >= 90 THEN 'A' WHEN grade >= 80 THEN 'B' WHEN grade >= 70 THEN 'C' WHEN grade >= 60 THEN 'D' ELSE 'F' END AS letter_grade FROM enrollments WHERE grade IS NOT NULL ORDER BY grade DESC LIMIT 6;
| enrollment_id | grade | letter_grade |
|---|---|---|
| 135 | 100 | A |
| 322 | 100 | A |
| 500 | 100 | A |
| 699 | 100 | A |
| 814 | 100 | A |
| 1 096 | 100 | A |
6 qator
1 ms
:::gotcha ⚠️ Tartib muhim — va shuning uchun yuqori chegara kerak emas
Talabalar ko'pincha WHEN grade >= 80 AND grade < 90 THEN 'B' deb yozadi. Yuqori chegara ortiqcha: SQL o'sha qatorga yetganda 90 va undan yuqori barcha baholar allaqachon mos kelib chiqib ketgan bo'ladi. Shartlarni yuqoridan pastga yozish butun ishni soddalashtiradi.
Endi tartibni teskari qiling va buzilishini kuzating: WHEN grade >= 60 THEN 'D' ni birinchi qo'ysangiz, har bir o'tgan baho D bo'lib qoladi, chunki 100 ham >= 60 shartini qanoatlantiradi. Talabalarga bu xatoni bir marta ataylab qildiring.
:::
grade IS NULL ataylab birinchi shox. Uni tashlab ketsangiz, baholanmagan enrollment lar barcha raqamli solishtirishlardan o'tib ketadi (hammasi UNKNOWN) va ELSE ga tushadi — ya'ni hali baholanmagan student F deb ko'rsatiladi. Bu haqiqatan zararli va ko'zga ko'rinmaydigan xato.
CASE ning ikkita ko'rinishi
-- Searched CASE: har qanday shart. 95% holatda shuni ishlating. CASE WHEN status = 'completed' THEN 'tugatildi' WHEN status = 'active' THEN 'davom etmoqda' ELSE 'boshqa' END -- Simple CASE: qisqaroq, lekin faqat bitta ifodaga tenglikni tekshiradi CASE status WHEN 'completed' THEN 'tugatildi' WHEN 'active' THEN 'davom etmoqda' ELSE 'boshqa' END
:::gotcha ⚠️ Simple CASE NULL ni topa olmaydi
CASE status WHEN NULL THEN ... hech qachon ishlamaydi, chunki u status = NULL ga aylanadi — abadiy UNKNOWN. Faqat searched ko'rinish WHEN status IS NULL ni tekshira oladi. NULL bo'lishi mumkin bo'lganda searched ko'rinishni ishlating.
:::
ORDER BY dagi CASE — o'z tartibingiz
Alifbo tartibi kamdan-kam odam xohlagan tartib bo'ladi. CASE o'zingizniki belgilash imkonini beradi:
SELECT enrollment_id, status FROM enrollments ORDER BY CASE status WHEN 'active' THEN 1 WHEN 'completed' THEN 2 WHEN 'failed' THEN 3 WHEN 'dropped' THEN 4 ELSE 5 END, enrollment_id;
| enrollment_id | status |
|---|---|
| 2 | active |
| 4 | active |
| 5 | active |
| 7 | active |
| 10 | active |
| 22 | active |
| 23 | active |
| 24 | active |
| 25 | active |
| 27 | active |
| 31 | active |
| 40 | active |
| 41 | active |
| 42 | active |
| 46 | active |
… 2500 qatordan birinchi 15 tasi
2500 qator
2 ms
Yana bir ko'p ishlatiladigan usul — database ning standartidan qat'i nazar NULL larni oxiriga majburlash:
ORDER BY CASE WHEN city IS NULL THEN 1 ELSE 0 END, city;
Aggregate ichidagi CASE (pivot)
Bu — butun bobdagi eng qimmatli pattern. CASE ni SUM yoki COUNT ichiga qo'yish row larni column larga aylantiradi — sof SQL da pivot table.
SELECT course_id, COUNT(*) AS total, SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed, SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) AS active, SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed, SUM(CASE WHEN status = 'dropped' THEN 1 ELSE 0 END) AS dropped FROM enrollments GROUP BY course_id ORDER BY course_id;
| course_id | total | completed | active | failed | dropped |
|---|---|---|---|---|---|
| 1 | 193 | 130 | 41 | 2 | 20 |
| 2 | 186 | 134 | 26 | 12 | 14 |
| 3 | 174 | 81 | 39 | 47 | 7 |
| 4 | 167 | 111 | 36 | 8 | 12 |
| 5 | 167 | 110 | 33 | 15 | 9 |
| 6 | 174 | 114 | 34 | 4 | 22 |
| 7 | 165 | 120 | 32 | 2 | 11 |
| 8 | 170 | 118 | 27 | 13 | 12 |
| 9 | 161 | 112 | 32 | 6 | 11 |
| 10 | 179 | 139 | 21 | 8 | 11 |
| 11 | 200 | 116 | 45 | 24 | 15 |
| 13 | 187 | 123 | 31 | 4 | 29 |
| 14 | 189 | 125 | 38 | 10 | 16 |
| 15 | 188 | 101 | 37 | 37 | 13 |
14 qator
1 ms
course_idtotalcompletedactivefaileddropped
152120 255000 332001 432100 541300
Buni 4-bobdagi GROUP BY course_id, status bilan solishtiring: u har bir birikma uchun bitta row beradi va bo'shlarini tashlab ketadi. Bu esa haqiqiy to'r beradi, real nol lar bilan. Rahbariyat aynan shunisiga qarashni xohlaydi.
```sql run -- ELSE siz COUNT(CASE ...) — NULL sanalmaydi, shuning uchun bu ham ishlaydi COUNT(CASE WHEN status = 'failed' THEN 1 END) AS failed
-- Qism ustidan AVG — bu yerda "ELSE 0" YO'Q, aks holda nol lar o'rtachani pastga tortadi AVG(CASE WHEN status = 'completed' THEN grade END) AS avg_completed_grade ```
ELSE 0 farqi — asosiy tuzoq: SUM/sanash uchun to'g'ri, AVG uchun noto'g'ri.
Xuddi shu pattern shartli foizni ham beradi — 4-bobdagi o'tish foizi idiomi:
SELECT course_id, COUNT(*) AS graded, ROUND(100.0 * SUM(CASE WHEN grade >= 60 THEN 1 ELSE 0 END) / COUNT(*), 1) AS pass_pct FROM enrollments WHERE grade IS NOT NULL GROUP BY course_id;
| course_id | graded | pass_pct |
|---|---|---|
| 1 | 132 | 98.5 |
| 2 | 146 | 91.8 |
| 3 | 128 | 63.3 |
| 4 | 119 | 93.3 |
| 5 | 125 | 88 |
| 6 | 118 | 96.6 |
| 7 | 122 | 98.4 |
| 8 | 131 | 90.1 |
| 9 | 118 | 94.9 |
| 10 | 147 | 94.6 |
| 11 | 140 | 82.9 |
| 13 | 127 | 96.9 |
| 14 | 135 | 92.6 |
| 15 | 138 | 73.2 |
14 qator
1 ms
String function lar
FunctionNima qiladiMisol → natija
UPPER(s) / LOWER(s)Harf holatini o'zgartiradiUPPER('aziza') → AZIZA
LENGTH(s)Belgilar soniLENGTH('Aziza') → 5
SUBSTR(s, start, len)Qismini ajratadi (1 dan boshlanadi!)SUBSTR('Karimova',1,3) → Kar
REPLACE(s, from, to)Barcha uchrashlarni almashtiradiREPLACE('a-b-c','-','.') → a.b.c
TRIM(s) / LTRIM / RTRIMChetdagi bo'shliqlarni olib tashlaydiTRIM(' hi ') → hi
INSTR(s, sub)Qism o'rni, yo'q bo'lsa 0INSTR('a@b.uz','@') → 2
a || bBirlashtiradi'A' || 'B' → AB
SELECT first_name || ' ' || last_name AS full_name, SUBSTR(first_name,1,1) || SUBSTR(last_name,1,1) AS initials, LOWER(first_name) || '.' || LOWER(last_name) || '@school.uz' AS email, LENGTH(first_name || last_name) AS name_length FROM students LIMIT 4;
| full_name | initials | name_length | |
|---|---|---|---|
| Shahnoza Alimova | SA | shahnoza.alimova@school.uz | 15 |
| Doston Umarov | DU | doston.umarov@school.uz | 12 |
| Zulfiya Yusupova | ZY | zulfiya.yusupova@school.uz | 15 |
| Kamola Karimova | KK | kamola.karimova@school.uz | 14 |
4 qator
0 ms
:::gotcha ⚠️ SQL da string 0 dan emas, 1 dan boshlanadi
Har bir Python dasturchisi bunga bir marta qoqiladi. SUBSTR(s, 1, 3) — birinchi uchta belgi; SUBSTR(s, 0, 3) esa kutilmagan boshqa narsa qiladi. SQL da hech qayerda noldan boshlanuvchi indeks yo'q.
:::
Dialect izohi: string function nomlari SQL ning eng kam universal qismlaridan biri.
| Vazifa | SQLite | PostgreSQL | MySQL | SQL Server |
|---|---|---|---|---|
| Birlashtirish | || |
|| |
CONCAT() |
+ |
| Qism ajratish | SUBSTR |
SUBSTRING |
SUBSTRING |
SUBSTRING |
| Uzunlik | LENGTH |
LENGTH |
LENGTH |
LEN |
| O'rni | INSTR |
POSITION/STRPOS |
LOCATE |
CHARINDEX |
| Row larga ajratish | — | string_to_table |
SUBSTRING_INDEX |
STRING_SPLIT |
Iflos matnni tozalash
Real hayotdagi eng ko'p uchraydigan ikkita matn muammosi va ikkalasini ham WHERE ichida tuzatish:
-- 1-muammo: ko'rinmas oldingi/keyingi bo'shliqlar. -- 'Tashkent ' <> 'Tashkent', shuning uchun bu row hech qachon mos kelmaydi. SELECT * FROM students WHERE TRIM(city) = 'Tashkent'; -- 2-muammo: har xil harf holati ('TASHKENT', 'tashkent', 'Tashkent') SELECT * FROM students WHERE LOWER(TRIM(city)) = 'tashkent'; -- Ikkalasi birga, tozalangan chiqish column i sifatida SELECT city AS raw, UPPER(SUBSTR(TRIM(LOWER(city)),1,1)) || SUBSTR(TRIM(LOWER(city)),2) AS cleaned -- 'Tashkent' FROM students;
1-natija
| student_id | first_name | last_name | gender | city | birth_date | enrolled_date |
|---|---|---|---|---|---|---|
| 8 | Madina | Rahimova | F | Tashkent | 2000-05-29 | 2025-02-09 |
| 12 | Rustam | Toshev | M | Tashkent | 2001-02-12 | 2025-09-08 |
| 19 | Aziza | Saidova | F | Tashkent | 2003-12-08 | 2025-02-10 |
| 20 | Aziza | Karimova | F | Tashkent | 2003-01-18 | 2025-09-03 |
| 27 | Zulfiya | Karimova | F | Tashkent | 2002-06-30 | 2025-02-13 |
| 30 | Gulnora | Yusupova | F | Tashkent | 2001-11-13 | 2025-02-12 |
| 31 | Dilnoza | Saidova | F | Tashkent | 1998-09-26 | 2025-09-01 |
| 39 | Aziz | Toshev | M | Tashkent | 2004-06-28 | 2025-09-03 |
| 40 | Aziza | Alimova | F | Tashkent | 2000-07-21 | 2025-02-05 |
| 43 | Malika | Ergasheva | F | Tashkent | 2001-02-13 | 2025-09-04 |
| 44 | Shohrux | Rahimov | M | Tashkent | 2004-04-24 | 2025-09-07 |
| 45 | Nilufar | Nazarova | F | Tashkent | 2001-12-24 | 2025-09-11 |
| 50 | Otabek | Alimov | M | Tashkent | 2002-12-30 | 2025-02-10 |
| 56 | Sardor | Saidov | M | Tashkent | 2001-06-11 | 2025-09-01 |
| 64 | Gulnora | Alimova | F | Tashkent | 2000-06-20 | 2025-02-19 |
… 82 qatordan birinchi 15 tasi
82 qator
2-natija
| student_id | first_name | last_name | gender | city | birth_date | enrolled_date |
|---|---|---|---|---|---|---|
| 8 | Madina | Rahimova | F | Tashkent | 2000-05-29 | 2025-02-09 |
| 12 | Rustam | Toshev | M | Tashkent | 2001-02-12 | 2025-09-08 |
| 19 | Aziza | Saidova | F | Tashkent | 2003-12-08 | 2025-02-10 |
| 20 | Aziza | Karimova | F | Tashkent | 2003-01-18 | 2025-09-03 |
| 27 | Zulfiya | Karimova | F | Tashkent | 2002-06-30 | 2025-02-13 |
| 30 | Gulnora | Yusupova | F | Tashkent | 2001-11-13 | 2025-02-12 |
| 31 | Dilnoza | Saidova | F | Tashkent | 1998-09-26 | 2025-09-01 |
| 39 | Aziz | Toshev | M | Tashkent | 2004-06-28 | 2025-09-03 |
| 40 | Aziza | Alimova | F | Tashkent | 2000-07-21 | 2025-02-05 |
| 43 | Malika | Ergasheva | F | Tashkent | 2001-02-13 | 2025-09-04 |
| 44 | Shohrux | Rahimov | M | Tashkent | 2004-04-24 | 2025-09-07 |
| 45 | Nilufar | Nazarova | F | Tashkent | 2001-12-24 | 2025-09-11 |
| 50 | Otabek | Alimov | M | Tashkent | 2002-12-30 | 2025-02-10 |
| 56 | Sardor | Saidov | M | Tashkent | 2001-06-11 | 2025-09-01 |
| 64 | Gulnora | Alimova | F | Tashkent | 2000-06-20 | 2025-02-19 |
… 82 qatordan birinchi 15 tasi
82 qator
3-natija
| raw | cleaned |
|---|---|
| Bukhara | Bukhara |
| Fergana | Fergana |
| Samarkand | Samarkand |
| Samarkand | Samarkand |
| Namangan | Namangan |
| Samarkand | Samarkand |
| Karshi | Karshi |
| Tashkent | Tashkent |
| Bukhara | Bukhara |
| Andijan | Andijan |
| Karshi | Karshi |
| Tashkent | Tashkent |
| Namangan | Namangan |
| Andijan | Andijan |
| Namangan | Namangan |
… 300 qatordan birinchi 15 tasi
300 qator
1 ms
:::gotcha ⚠️ WHERE ichida tozalash index ni yo'qotadi
WHERE LOWER(TRIM(city)) = 'tashkent' to'g'ri, lekin to'liq scan ga majbur qiladi (3-bobdagi non-sargable qoidasi). Bir martalik tahlil uchun bu yaxshi. Doim ishlaydigan query uchun esa haqiqiy yechim — data ni kirish paytida tozalash: bir marta UPDATE (10-bob), yoki iflos qiymatlarni umuman qabul qilmaydigan CHECK constraint.
:::
Nima qilishni hal qilishdan oldin iflos qiymatlarni topishning tez yo'li:
SELECT city, COUNT(*) AS n, CASE WHEN city <> TRIM(city) THEN 'bo''shliqli' ELSE 'toza' END AS issue FROM students GROUP BY city ORDER BY n DESC;
| city | n | issue |
|---|---|---|
| Tashkent | 82 | toza |
| Samarkand | 40 | toza |
| Bukhara | 38 | toza |
| Fergana | 36 | toza |
| Namangan | 28 | toza |
| Andijan | 24 | toza |
| Nukus | 22 | toza |
| Karshi | 22 | toza |
| None | 8 | toza |
9 qator
0 ms
Date va time function lar
SQLite sanalarni 'YYYY-MM-DD' matn sifatida saqlaydi va ular bilan ishlash uchun beshta function beradi.
| Function | Nima qaytaradi | Misol |
|---|---|---|
DATE(x) |
YYYY-MM-DD |
DATE('now') |
DATETIME(x) |
YYYY-MM-DD HH:MM:SS |
DATETIME('now','localtime') |
strftime(fmt, x) |
Istalgan formatlangan qism | strftime('%Y-%m', d) |
JULIANDAY(x) |
Kunlar soni — ayirish uchun | JULIANDAY(a) - JULIANDAY(b) |
| Modifikatorlar | Sanani siljitadi | DATE(d, '+1 month', '-1 day') |
| strftime kodi | Nima beradi | 2026-02-14 uchun |
|---|---|---|
%Y |
Yil | 2026 |
%m |
Oy (01–12) | 02 |
%d |
Kun | 14 |
%Y-%m |
Yil-oy — hisobotning asosiy quroli | 2026-02 |
%w |
Hafta kuni (0 = yakshanba) | 6 |
%j |
Yilning kuni | 045 |
%W |
Yilning haftasi | 06 |
SELECT enrolled_at, strftime('%Y', enrolled_at) AS year, strftime('%Y-%m', enrolled_at) AS year_month, strftime('%w', enrolled_at) AS weekday_num, CASE strftime('%w', enrolled_at) WHEN '0' THEN 'Yakshanba' WHEN '1' THEN 'Dushanba' WHEN '2' THEN 'Seshanba' WHEN '3' THEN 'Chorshanba' WHEN '4' THEN 'Payshanba' WHEN '5' THEN 'Juma' ELSE 'Shanba' END AS weekday FROM enrollments WHERE enrollment_id IN (1, 13, 19);
| enrolled_at | year | year_month | weekday_num | weekday |
|---|---|---|---|---|
| 2025-02-18 | 2025 | 2025-02 | 2 | Seshanba |
| 2025-02-13 | 2025 | 2025-02 | 4 | Payshanba |
| 2025-02-14 | 2025 | 2025-02 | 5 | Juma |
3 qator
0 ms
SELECT DATE('2026-02-14', '+7 days') AS week_later, -- 2026-02-21 DATE('2026-02-14', '-1 month') AS month_earlier, -- 2026-01-14 DATE('2026-02-14', 'start of month') AS month_start, -- 2026-02-01 DATE('2026-02-14', 'start of month', '+1 month', '-1 day') AS month_end, -- 2026-02-28 DATE('2026-02-14', 'start of year') AS year_start; -- 2026-01-01
| week_later | month_earlier | month_start | month_end | year_start |
|---|---|---|---|---|
| 2026-02-21 | 2026-01-14 | 2026-02-01 | 2026-02-28 | 2026-01-01 |
1 qator
0 ms
O'sha month_end zanjiri — 28/30/31 ni qo'lda yozmasdan va kabisa yili haqida o'ylamasdan istalgan oyning oxirgi kunini olishning standart usuli.
Sana arifmetikasi — yosh va oraliqlar
Sanalarni ayirish uchun JULIANDAY kerak, u sanani oddiy kunlar soniga aylantiradi.
SELECT first_name, birth_date, CAST((JULIANDAY('2026-09-01') - JULIANDAY(birth_date)) / 365.25 AS INTEGER) AS age FROM students ORDER BY age DESC;
| first_name | birth_date | age |
|---|---|---|
| Gulnora | 1998-03-21 | 28 |
| Aziz | 1998-05-23 | 28 |
| Gulnora | 1998-08-23 | 28 |
| Otabek | 1998-05-31 | 28 |
| Shohrux | 1998-04-07 | 28 |
| Ulug'bek | 1998-03-05 | 28 |
| Zulfiya | 1998-06-24 | 28 |
| Doston | 1998-05-18 | 28 |
| Doston | 1998-05-15 | 28 |
| Kamola | 1998-04-15 | 28 |
| Ulug'bek | 1998-08-09 | 28 |
| Zulfiya | 1998-05-13 | 28 |
| Kamola | 1998-04-14 | 28 |
| Shahnoza | 1998-05-29 | 28 |
| Akmal | 1998-07-30 | 28 |
… 300 qatordan birinchi 15 tasi
300 qator
1 ms
:::gotcha ⚠️ Nega 365.25 va nega ROUND emas, CAST
365.25 kabisa yillarni hisobga oladi. CAST(... AS INTEGER) kesib tashlaydi, "yosh" degani ham shu — siz 22 ga to'lgan kuningizgacha 21 dasiz, olti oy oldin "22 ga yaxlitlangan" emas. Bu yerda ROUND ishlatish student laringizning yarmini bir yosh kattaroq qilib ko'rsatadi. Yana e'tibor bering: mos yozuvlar sanasi DATE('now') emas, aniq yozilgan — shunda jadvaldagi raqamlar darsingizda o'zgarmaydi.
:::
Hodisalar orasidagi oraliqlar — JULIANDAY ni 7-bobdagi LAG bilan birga:
SELECT student_id, enrolled_at, LAG(enrolled_at) OVER (PARTITION BY student_id ORDER BY enrolled_at) AS previous, CAST(JULIANDAY(enrolled_at) - JULIANDAY(LAG(enrolled_at) OVER (PARTITION BY student_id ORDER BY enrolled_at)) AS INTEGER) AS days_since_last FROM enrollments WHERE student_id IN (1, 3) ORDER BY student_id, enrolled_at;
| student_id | enrolled_at | previous | days_since_last |
|---|---|---|---|
| 1 | 2025-09-06 | None | NaN |
| 1 | 2025-09-07 | 2025-09-06 | 1 |
| 1 | 2025-09-09 | 2025-09-07 | 2 |
| 1 | 2025-09-13 | 2025-09-09 | 4 |
| 1 | 2025-09-13 | 2025-09-13 | 0 |
| 1 | 2025-09-17 | 2025-09-13 | 4 |
| 1 | 2025-09-26 | 2025-09-17 | 9 |
| 3 | 2025-02-17 | None | NaN |
| 3 | 2025-02-19 | 2025-02-17 | 2 |
| 3 | 2025-02-19 | 2025-02-19 | 0 |
| 3 | 2025-02-20 | 2025-02-19 | 1 |
| 3 | 2025-02-24 | 2025-02-20 | 4 |
| 3 | 2025-03-04 | 2025-02-24 | 8 |
| 3 | 2025-03-05 | 2025-03-04 | 1 |
| 3 | 2025-03-08 | 2025-03-05 | 3 |
… 16 qatordan birinchi 15 tasi
16 qator
0 ms
student_idenrolled_atpreviousdays_since_last
12025-09-05NULLNULL 12025-09-052025-09-050 12026-02-032025-09-05151 32025-09-18NULLNULL 32026-02-052025-09-18140 32026-02-052026-02-050
CAST va type o'zgartirish
SELECT CAST('42' AS INTEGER) AS text_to_int, -- 42 CAST(3.99 AS INTEGER) AS float_to_int, -- 3 (kesildi, yaxlitlanmadi!) CAST(7 AS REAL) AS int_to_real, -- 7.0 CAST(42 AS TEXT) AS int_to_text, -- '42' CAST('abc' AS INTEGER) AS bad_cast; -- SQLite da 0, PostgreSQL da XATO
| text_to_int | float_to_int | int_to_real | int_to_text | bad_cast |
|---|---|---|---|---|
| 42 | 3 | 7 | 42 | 0 |
1 qator
0 ms
:::gotcha ⚠️ INTEGER ga CAST kesadi; muvaffaqiyatsiz cast database ga qarab farq qiladi
CAST(3.99 AS INTEGER) — bu 4 emas, 3. Yaxlitlash kerak bo'lsa ROUND ishlating. Noto'g'ri cast esa SQLite da indamay 0 qaytaradi, PostgreSQL da xato beradi — ya'ni lokalda "ishlaydigan" data tozalash query si production da yiqilishi yoki battari, har bir o'qib bo'lmaydigan qiymatni jimgina nolga aylantirishi mumkin.
:::
Eng ko'p uchraydigan amaliy foydasi — 2-bobdagi haqiqiy bo'lishga majburlash:
SELECT 7 / 2 AS integer_division, -- 3 7 * 1.0 / 2 AS trick_multiply, -- 3.5 CAST(7 AS REAL) / 2 AS explicit_cast; -- 3.5
| integer_division | trick_multiply | explicit_cast |
|---|---|---|
| 3 | 3.5 | 3.5 |
1 qator
0 ms
Matematika va yaxlitlash
FunctionNima qiladiMisol → natija
ROUND(x, n)n kasrgacha yaxlitlaydiROUND(79.428, 2) → 79.43
ABS(x)ModulABS(-15) → 15
x % yQoldiq17 % 5 → 2
MIN(a,b) / MAX(a,b)Argumentlarning kichigi / kattasiMAX(10, 20) → 20
ABS, POWER, SQRTStandart matematikaSQRT(16) → 4.0
:::gotcha ⚠️ MIN ikki xil narsani anglatadi
Bitta argumentli MIN(grade) — aggregate, ya'ni ko'p row bo'ylab eng past baho. Ikkita argumentli MIN(a, b) esa bitta row ichidagi ikkita qiymatni solishtiradigan scalar function. Bir xil nom, butunlay boshqa xatti-harakat. (PostgreSQL chalkashlikni scalar variantni LEAST/GREATEST deb atash bilan hal qilgan.)
:::
Mashqlar to'plami
-- 1. Har bir baholangan enrollment uchun harfli baho SELECT enrollment_id, grade, CASE WHEN grade >= 90 THEN 'A' WHEN grade >= 80 THEN 'B' WHEN grade >= 70 THEN 'C' WHEN grade >= 60 THEN 'D' ELSE 'F' END AS letter FROM enrollments WHERE grade IS NOT NULL ORDER BY grade DESC; -- 2. Har bir harfli bahodan nechtadan? SELECT CASE WHEN grade >= 90 THEN 'A' WHEN grade >= 80 THEN 'B' WHEN grade >= 70 THEN 'C' WHEN grade >= 60 THEN 'D' ELSE 'F' END AS letter, COUNT(*) AS n FROM enrollments WHERE grade IS NOT NULL GROUP BY letter ORDER BY letter; -- 3. Course bo'yicha status pivot SELECT course_id, SUM(CASE WHEN status='completed' THEN 1 ELSE 0 END) AS completed, SUM(CASE WHEN status='active' THEN 1 ELSE 0 END) AS active, SUM(CASE WHEN status='failed' THEN 1 ELSE 0 END) AS failed FROM enrollments GROUP BY course_id; -- 4. Yaratilgan email manzillar SELECT LOWER(first_name) || '.' || LOWER(last_name) || '@school.uz' AS email FROM students; -- 5. Har bir student ning yoshi SELECT first_name, CAST((JULIANDAY('2026-09-01') - JULIANDAY(birth_date))/365.25 AS INTEGER) AS age FROM students ORDER BY age DESC; -- 6. Course lar bo'yicha narx darajasi SELECT title, price, CASE WHEN price >= 2500000 THEN 'premium' WHEN price >= 1400000 THEN 'standart' ELSE 'oddiy' END AS price_band FROM courses ORDER BY price DESC; -- 7. Hafta kunlari bo'yicha enrollment lar SELECT strftime('%w', enrolled_at) AS weekday_num, COUNT(*) AS n FROM enrollments GROUP BY weekday_num ORDER BY weekday_num; -- 8. Student larni yosh guruhlariga ajratish SELECT CASE WHEN CAST((JULIANDAY('2026-09-01')-JULIANDAY(birth_date))/365.25 AS INTEGER) <= 21 THEN '21 va undan kichik' ELSE '22 va undan katta' END AS age_band, COUNT(*) AS n FROM students GROUP BY age_band;
1-natija
| enrollment_id | grade | letter |
|---|---|---|
| 135 | 100 | A |
| 322 | 100 | A |
| 500 | 100 | A |
| 699 | 100 | A |
| 814 | 100 | A |
| 1 096 | 100 | A |
| 1 202 | 100 | A |
| 1 832 | 100 | A |
| 1 862 | 100 | A |
| 2 126 | 100 | A |
| 2 128 | 100 | A |
| 2 161 | 100 | A |
| 2 377 | 100 | A |
| 2 424 | 100 | A |
| 483 | 99 | A |
… 1826 qatordan birinchi 15 tasi
1826 qator
2-natija
| letter | n |
|---|---|
| A | 115 |
| B | 379 |
| C | 665 |
| D | 475 |
| F | 192 |
5 qator
3-natija
| course_id | completed | active | failed |
|---|---|---|---|
| 1 | 130 | 41 | 2 |
| 2 | 134 | 26 | 12 |
| 3 | 81 | 39 | 47 |
| 4 | 111 | 36 | 8 |
| 5 | 110 | 33 | 15 |
| 6 | 114 | 34 | 4 |
| 7 | 120 | 32 | 2 |
| 8 | 118 | 27 | 13 |
| 9 | 112 | 32 | 6 |
| 10 | 139 | 21 | 8 |
| 11 | 116 | 45 | 24 |
| 13 | 123 | 31 | 4 |
| 14 | 125 | 38 | 10 |
| 15 | 101 | 37 | 37 |
14 qator
4-natija
| shahnoza.alimova@school.uz |
| doston.umarov@school.uz |
| zulfiya.yusupova@school.uz |
| kamola.karimova@school.uz |
| gulnora.saidova@school.uz |
| bekzod.yusupov@school.uz |
| doston.alimov@school.uz |
| madina.rahimova@school.uz |
| sardor.alimov@school.uz |
| dilnoza.alimova@school.uz |
| jasur.ergashev@school.uz |
| rustam.toshev@school.uz |
| bekzod.qodirov@school.uz |
| otabek.saidov@school.uz |
| madina.umarova@school.uz |
… 300 qatordan birinchi 15 tasi
300 qator
5-natija
| first_name | age |
|---|---|
| Gulnora | 28 |
| Aziz | 28 |
| Gulnora | 28 |
| Otabek | 28 |
| Shohrux | 28 |
| Ulug'bek | 28 |
| Zulfiya | 28 |
| Doston | 28 |
| Doston | 28 |
| Kamola | 28 |
| Ulug'bek | 28 |
| Zulfiya | 28 |
| Kamola | 28 |
| Shahnoza | 28 |
| Akmal | 28 |
… 300 qatordan birinchi 15 tasi
300 qator
6-natija
| title | price | price_band |
|---|---|---|
| Deep Learning | 1 550 000 | standart |
| Project Management | 1 500 000 | standart |
| Financial Analysis | 1 500 000 | standart |
| Machine Learning | 1 450 000 | standart |
| Probability | 1 250 000 | oddiy |
| Python Basics | 1 200 000 | oddiy |
| Statistics 101 | 1 200 000 | oddiy |
| Linear Algebra | 1 200 000 | oddiy |
| Web Development | 1 150 000 | oddiy |
| Java Basics | 1 150 000 | oddiy |
| Excel for Business | 1 100 000 | oddiy |
| Graphic Design | 950 000 | oddiy |
| Data Visualization | 900 000 | oddiy |
| UX Design | 850 000 | oddiy |
| SQL for Analytics | 800 000 | oddiy |
15 qator
7-natija
| weekday_num | n |
|---|---|
| 0 | 345 |
| 1 | 327 |
| 2 | 358 |
| 3 | 405 |
| 4 | 358 |
| 5 | 331 |
| 6 | 376 |
7 qator
8-natija
| age_band | n |
|---|---|
| 21 va undan kichik | 13 |
| 22 va undan katta | 287 |
2 qator
5 ms
Intervyu savollari
S: CASE qaysi shoxni tanlashini qanday hal qiladi?
Shartlarni yuqoridan pastga tekshiradi va TRUE bo'lgan birinchisini qaytaradi, shuning uchun tartib muhim. Hech biri mos kelmasa va ELSE bo'lmasa, NULL qaytaradi.
S: Sof SQL da pivot table ni qanday quriladi?
Har bir chiqish column i uchun bittadan SUM(CASE WHEN col = 'qiymat' THEN 1 ELSE 0 END) AS qiymat yozib, row o'lchovi bo'yicha GROUP BY qilinadi.
S: Nega AVG(CASE ...) ichida ELSE 0 noto'g'ri?
Chunki u mos kelmagan row larni chiqarib tashlash o'rniga o'rtachaga kiradigan nol larga aylantiradi. ELSE ni yozmang — shunda ular NULL bo'ladi va AVG ularni tashlab ketadi.
S: Simple va searched CASE farqi?
Simple CASE expr WHEN v THEN ... faqat bitta ifodaga tenglikni tekshiradi va NULL ni topa olmaydi. Searched CASE WHEN shart THEN ... esa har qanday shartga, jumladan IS NULL ga ruxsat beradi.
S: SUBSTR 0 dan boshlanadimi yoki 1 dan?
1 dan. Birinchi belgi — 1-o'rin.
S: Oyning oxirgi kunini qanday olasiz?
Oy boshiga o'ting, bir oy qo'shing, bir kun ayiring: DATE(d,'start of month','+1 month','-1 day'). Hech qachon 30 yoki 31 ni qo'lda yozmang.
S: Katta table da WHERE UPPER(name) = 'ALI' nimasi bilan yomon?
Column ustidagi function uni non-sargable qiladi, ya'ni hech qanday index ishlatilmaydi. Query paytida column ni o'rash o'rniga data ni tuzating yoki functional index qo'shing.
S: CAST(3.99 AS INTEGER) — 3 mi, 4 mi?
CASTkesadi. 4 kerak bo'lsaROUNDishlating.
Xulosa
CASE WHEN— SQL ning if/else i. Shartlar tartib bilan tekshiriladi, shuning uchun ularni yuqoridan pastga yozing va NULL tekshiruvini birinchi qo'ying — aks holda baholanmagan row lar indamay F bo'lib qoladi.- Simple
CASENULL ni topa olmaydi; searched ko'rinish topa oladi. ORDER BYdagiCASEo'z saralash tartibingizni va NULL ning o'rnini belgilaydi.SUM(CASE WHEN ... THEN 1 ELSE 0 END)— pivot idiomi: row lar column ga aylanadi, real nol lar bilan. AggregateAVGbo'lsaELSE 0ni tashlang.- String ishlari:
||,UPPER/LOWER,SUBSTR(1 dan),TRIM,REPLACE,LENGTH,INSTR. Nomlar database lar orasida ancha farq qiladi. TRIM+LOWERiflos matnning ko'pini tuzatadi, lekinWHEREichida tozalash index ni yo'qotadi — saqlangan data ni tozalang.- Sanalar: ajratish uchun
strftime, siljitish uchunDATE(d, modifikator), ayirish uchunJULIANDAY.'start of month','+1 month','-1 day'oy oxirini xavfsiz beradi. - Yosh =
CAST(kunlar / 365.25 AS INTEGER)— kesing, hech qachon yaxlitlamang. - INTEGER ga
CASTkesadi; noto'g'ri cast SQLite da indamay 0, PostgreSQL da esa xato.
Keyingi: 9-bob — UNION, INTERSECT va EXCEPT bilan query natijalarini bir-birining ustiga qo'yish.
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.