# SQL HAVING — guruhlarni filtrlash

> SQL HAVING bilan GROUP BY guruhlarini filtrlash. WHERE va HAVING o'rtasidagi farq hamda ikkalasini bitta so'rovda birga ishlatishni misolda o'rganamiz.

Manba: https://learncode.uz/sql/having/
Sana: 2026-06-15

[`GROUP BY`](https://learncode.uz/sql/group-by) darsida qatorlarni guruhlab, har guruh uchun
hisob chiqarishni ko'rdik. Endi savol: agar faqat **ba'zi** guruhlar kerak
bo'lsa-chi? Masalan "faqat 2 va undan ko'p mahsuloti bor toifalar". Bu yerda
[`WHERE`](https://learncode.uz/sql/where) yordam bermaydi — chunki u guruhlashdan **oldin**
ishlaydi. Guruhlarni filtrlash uchun **`HAVING`** bor.

## Muammo: WHERE guruhni ko'rmaydi

Mahsulotlarni toifa (`turi`) bo'yicha guruhlab, har toifada nechta borligini
sanaymiz:

```sql
SELECT turi, COUNT(*) AS soni
FROM mahsulotlar
GROUP BY turi;
```

Natija:

| turi | soni |
|---|---|
| don | 1 |
| ichimlik | 2 |
| meva | 2 |
| non | 1 |
| sut mahsuloti | 2 |

Endi faqat `soni >= 2` bo'lgan toifalarni xohlaymiz. `WHERE soni >= 2`
yozsak — **xato**, chunki `WHERE` alohida qatorlarni tekshiradi, guruh
natijasini emas. `COUNT(*)` esa faqat guruhlashdan keyin paydo bo'ladi.

## Yechim: HAVING

`HAVING` xuddi `WHERE` kabi filtrlaydi, lekin **guruhlar** ustidan —
`GROUP BY` dan keyin ishlaydi:

```sql
SELECT turi, COUNT(*) AS soni
FROM mahsulotlar
GROUP BY turi
HAVING COUNT(*) >= 2;
```

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

```sql
SELECT turi, COUNT(*) AS soni
FROM mahsulotlar
GROUP BY turi
HAVING COUNT(*) >= 2;
```

Natija — bittalik toifalar (don, non) tushib qoldi:

| turi | soni |
|---|---|
| ichimlik | 2 |
| meva | 2 |
| sut mahsuloti | 2 |

> **Atama**
>
> **WHERE va HAVING farqi:** `WHERE` — guruhlashdan **oldin**, alohida
> qatorlarni filtrlaydi. `HAVING` — guruhlashdan **keyin**, guruh natijasini
> (masalan `COUNT`, `SUM`) filtrlaydi. Qoida: agar shartda
> [agregat funksiya](https://learncode.uz/sql/agregat-funksiyalar) bo'lsa — `HAVING`, bo'lmasa
> — `WHERE`.

## WHERE va HAVING birga

Ikkalasi bitta so'rovda birga ishlashi mumkin va bu tez-tez uchraydi. Avval
`WHERE` keraksiz qatorlarni chiqarib tashlaydi, keyin qolganlari guruhlanadi,
so'ng `HAVING` guruhlarni filtrlaydi.

Masalan: narxi 5000 dan qimmat mahsulotlarni olib, toifa bo'yicha guruhlab,
faqat 2 va undan ko'p a'zosi borlarini ko'rsatamiz:

```sql
SELECT turi, COUNT(*) AS soni
FROM mahsulotlar
WHERE narx > 5000
GROUP BY turi
HAVING COUNT(*) >= 2;
```

Natija:

| turi | soni |
|---|---|
| meva | 2 |
| sut mahsuloti | 2 |

`WHERE narx > 5000` Non (3000) va Suv (4000) ni oldindan chiqarib tashladi;
shundan keyin qolgan mahsulotlar guruhlandi va `HAVING` bittalik guruhlarni
olib tashladi.

> **Boshlovchilar tez-tez yanglishadigan joy**
>
> So'rov qismlarining **tartibi** qat'iy: `WHERE` doim `GROUP BY` dan oldin,
> `HAVING` doim `GROUP BY` dan keyin yoziladi. Ularning o'rnini almashtirsangiz,
> SQL xato beradi.

<Callout type="example" title="O'zingizni sinab ko'ring">
[`buyurtmalar`](https://learncode.uz/sql/join) jadvalida har mijoz nechta buyurtma berganini
sanab, faqat 2 dan ko'p bergani chiqaring:

```sql
SELECT mijoz_id, COUNT(*) AS buyurtmalar_soni
FROM buyurtmalar
GROUP BY mijoz_id
HAVING COUNT(*) > 2;
```

Natijada faqat `mijoz_id = 1` (Aziz, 3 ta buyurtma) chiqadi.
</Callout>

## Amaliy mashq

Guruhlarni filtrlang:

1. Har toifadagi mahsulotlar sonini chiqaring;
2. `HAVING COUNT(*) > 1` bilan faqat bittadan ko'p bo'lganlarni qoldiring;
3. `HAVING` o'rniga `WHERE COUNT(*) > 1` yozib ko'ring — nima bo'ldi?
4. `HAVING AVG(narx) > 10000` bilan qimmat toifalarni toping;
5. `WHERE` va `HAVING` ni bitta so'rovda birga ishlating;
6. `buyurtmalar` da sinang: `mijoz_id` bo'yicha guruhlab,
   `HAVING SUM(soni) > 5` bilan ko'p dona olgan mijozlarni ajrating.

3-qadamdagi xato `WHERE` va `HAVING` farqini tushuntiradi.

## Qisqacha xulosa

- `HAVING` — `GROUP BY` guruhlarini filtrlaydi (guruhlashdan **keyin**).
- `WHERE` — alohida qatorlarni filtrlaydi (guruhlashdan **oldin**).
- Shartda `COUNT`/`SUM`/`AVG` bo'lsa → `HAVING`; oddiy ustun bo'lsa → `WHERE`.
- Ikkalasi birga ishlaydi: `WHERE → GROUP BY → HAVING` tartibida.
- Tartib qat'iy: `HAVING` doim `GROUP BY` dan keyin turadi.

Keyingi darsda [subquery](https://learncode.uz/sql/subquery) — bitta so'rov ichida ikkinchi
so'rov yozishni ko'ramiz.
