SQL HAVING — guruhlarni filtrlash
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 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:
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:
SELECT turi, COUNT(*) AS soni
FROM mahsulotlar
GROUP BY turi
HAVING COUNT(*) >= 2;
O’zingiz ishga tushirib ko’ring — so’rovni tahrirlashingiz ham mumkin:
Natija — bittalik toifalar (don, non) tushib qoldi:
| turi | soni |
|---|---|
| ichimlik | 2 |
| meva | 2 |
| sut mahsuloti | 2 |
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:
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.
Amaliy mashq
Guruhlarni filtrlang:
- Har toifadagi mahsulotlar sonini chiqaring;
HAVING COUNT(*) > 1bilan faqat bittadan ko’p bo’lganlarni qoldiring;HAVINGo’rnigaWHERE COUNT(*) > 1yozib ko’ring — nima bo’ldi?HAVING AVG(narx) > 10000bilan qimmat toifalarni toping;WHEREvaHAVINGni bitta so’rovda birga ishlating.
3-qadamdagi xato WHERE va HAVING farqini tushuntiradi.
Qisqacha xulosa
HAVING—GROUP BYguruhlarini filtrlaydi (guruhlashdan keyin).WHERE— alohida qatorlarni filtrlaydi (guruhlashdan oldin).- Shartda
COUNT/SUM/AVGbo’lsa →HAVING; oddiy ustun bo’lsa →WHERE. - Ikkalasi birga ishlaydi:
WHERE → GROUP BY → HAVINGtartibida. - Tartib qat’iy:
HAVINGdoimGROUP BYdan keyin turadi.
Keyingi darsda subquery — bitta so’rov ichida ikkinchi so’rov yozishni ko’ramiz.