# SQL subquery — so'rov ichidagi so'rov

> SQL subquery (ichki so'rov): bitta so'rov natijasini ikkinchi so'rovda ishlatish. O'rtacha narxdan qimmat mahsulotlar va IN bilan filtrlash misollari.

Manba: https://learncode.uz/sql/subquery/
Sana: 2026-06-16

Ba'zan bitta so'rov yetmaydi: avval bir narsani hisoblab, keyin o'sha natija
asosida filtrlash kerak bo'ladi. Masalan "o'rtacha narxdan qimmat
mahsulotlar". O'rtacha narxni oldindan bilmaymiz — uni ham so'rov chiqaradi.
Shu yerda **subquery** (ichki so'rov) ish beradi: bitta so'rov ichiga
ikkinchisini joylaymiz.

## Muammo: ikki qadamli savol

"Narxi o'rtachadan yuqori mahsulotlarni ko'rsat" degan savolda ikki qadam bor:

1. O'rtacha narxni hisoblash.
2. Har mahsulotni shu qiymat bilan solishtirish.

Buni ikki so'rovga bo'lib qilsa bo'ladi, lekin subquery ikkalasini bitta
so'rovga jamlaydi.

## Subquery WHERE ichida

Ichki so'rov qavs ichida yoziladi va avval **u** hisoblanadi, keyin natijasi
tashqi so'rovga beriladi:

```sql
SELECT nom, narx
FROM mahsulotlar
WHERE narx > (SELECT AVG(narx) FROM mahsulotlar);
```

O'zingiz ishga tushirib ko'ring — so'rovni tahrirlashingiz ham mumkin:

```sql
SELECT nom, narx FROM mahsulotlar
WHERE narx > (SELECT AVG(narx) FROM mahsulotlar);
```

Bu yerda `(SELECT AVG(narx) FROM mahsulotlar)` avval ishlaydi va `10375` ni
qaytaradi. So'ng tashqi so'rov `narx > 10375` shartini tekshiradi:

| nom | narx |
|---|---|
| Sut | 12000 |
| Choy | 15000 |
| Banan | 14000 |
| Guruch | 18000 |

Diqqat: `AVG` natijasini qo'lda yozib qo'ymadik. Ertaga narxlar o'zgarsa,
so'rov o'zi qayta hisoblaydi — mana shu subquery'ning qulayligi.

> **Atama**
>
> **Subquery** (ichki so'rov) — boshqa so'rov ichiga qavs bilan joylangan
> `SELECT`. Avval ichki so'rov bajariladi, uning natijasi tashqi so'rovda
> ishlatiladi. Uni "so'rov ichidagi so'rov" deb tasavvur qiling.

## Subquery IN bilan

Ichki so'rov bitta qiymat emas, **ro'yxat** qaytarganda
[`IN`](https://learncode.uz/sql/operatorlar) bilan ishlatiladi. Masalan, kamida bitta buyurtma
bergan mijozlarni topamiz:

```sql
SELECT ism
FROM mijozlar
WHERE id IN (SELECT mijoz_id FROM buyurtmalar);
```

Ichki so'rov buyurtma bergan mijozlar ro'yxatini (`1, 2, 3`) qaytaradi,
tashqi so'rov esa shu `id` li mijozlarni ko'rsatadi:

| ism |
|---|
| Aziz |
| Dilnoza |
| Bobur |

Malika ro'yxatda yo'q, chunki uning buyurtmasi yo'q.

<Callout type="example" title="O'zingizni sinab ko'ring">
`NOT IN` bilan aksini toping — hech narsa buyurtma qilmagan mijozlar:

```sql
SELECT ism
FROM mijozlar
WHERE id NOT IN (SELECT mijoz_id FROM buyurtmalar);
```

Natija: faqat **Malika**. Aynan shu natijani avvalgi darsda
[`LEFT JOIN`](https://learncode.uz/sql/join-turlari) bilan ham olgan edik — bir masalani ikki
usulda yechsa bo'ladi.
</Callout>

> **Boshlovchilar tez-tez yanglishadigan joy**
>
> `> (SELECT ...)` kabi solishtirish uchun ichki so'rov **bitta** qiymat
> qaytarishi kerak. Agar u ko'p qator qaytarsa, `>` xato beradi — bunday
> holatda `IN` ishlating. Bitta qiymat kutilganda `AVG`, `MAX`, `MIN` kabi
> funksiyalar qo'l keladi.

## Amaliy mashq

Ichki so'rov yozing:

1. O'rtacha narxni `AVG(narx)` bilan toping;
2. shu qiymatni ichki so'rov qilib, undan qimmat mahsulotlarni chiqaring;
3. `IN` bilan ichki so'rov yozing: buyurtma qilingan mahsulotlar;
4. `NOT IN` bilan hech kim buyurtma qilmagan mahsulotlarni toping;
5. ichki so'rovni alohida ishga tushirib, nima qaytarishini ko'ring;
6. `MAX(narx)` li ichki so'rov yozib, eng qimmat mahsulot nomini chiqaring.

5-qadam ichki so'rov nima qaytarayotganini to'g'ridan-to'g'ri ko'rsatadi.

## Qisqacha xulosa

- **Subquery** — qavs ichidagi `SELECT`; avval u, keyin tashqi so'rov ishlaydi.
- Bitta qiymat qaytarsa — `>`, `<`, `=` bilan solishtiriladi (masalan `AVG`).
- Ro'yxat qaytarsa — `IN` yoki `NOT IN` bilan ishlatiladi.
- Subquery hisoblangan qiymatni qo'lda yozib qo'yishdan qutqaradi — so'rov
  o'zi qayta hisoblaydi.
- Ichki so'rovni **alohida ishga tushirib** ko'ring — u nima qaytarayotganini
  ko'rsangiz, tashqi so'rov mantiqi aniq bo'ladi.

Keyingi darsda [primary key va foreign key](https://learncode.uz/sql/primary-foreign-key) —
jadvallarni ishonchli bog'lab turadigan **kalitlar**ni ko'ramiz.
