Saytdan foydalanishda muammoga duch kelsangiz, qo'llab-quvvatlash xizmatiga murojaat qiling: @fast_support_admin
Agregatsiyalar3 daqiqa o'qish

WHERE va HAVING farqi

WHERE qatorlarni guruhlashdan oldin, HAVING esa tayyor guruhlarni filtrlaydi. Qachon qaysi biri kerakligini va eng ko'p uchraydigan xatoni misol bilan ko'ramiz.

Ikkalasi ham "filtr", lekin turli bosqichda ishlaydi. WHERE alohida qatorlarni tekshiradi, HAVING esa GROUP BY yasagan guruhlarni. Farqni tushunsangiz, agregat bilan bog'liq xatolarning yarmi o'z-o'zidan yo'qoladi.

So'rov qaysi tartibda bajariladi

SQL ni yozish tartibi va bajarilish tartibi har xil. Ma'lumotlar bazasi taxminan shunday ishlaydi:

  1. FROM — jadval(lar) olinadi
  2. WHERE — qatorlar filtrlanadi
  3. GROUP BY — qolgan qatorlar guruhlanadi
  4. HAVING — guruhlar filtrlanadi
  5. SELECT — ustunlar hisoblanadi
  6. ORDER BY — saralanadi

Shundan asosiy qoida chiqadi: WHERE ishlayotgan paytda guruhlar hali yo'q, shuning uchun unda COUNT, SUM, AVG kabi agregatlarni ishlatib bo'lmaydi.

Jadval: orders

idcityamount
1Toshkent120000
2Toshkent45000
3Samarqand80000
4Toshkent300000
5Buxoro50000
6Samarqand15000

Vazifa

Qaysi shaharlarda 50 000 so'mdan katta buyurtmalar kamida 2 ta?

Bu yerda ikki xil shart bor:

  • "50 000 dan katta" — har bir qator haqida, demak WHERE
  • "kamida 2 ta" — guruh haqida, demak HAVING
To'g'ri yechim
SELECT city, COUNT(*) AS big_orders
FROM orders
WHERE amount > 50000
GROUP BY city
HAVING COUNT(*) >= 2;

Natija:

citybig_orders
Toshkent2

Qanday ishladi: WHERE 45 000, 50 000 va 15 000 lik qatorlarni olib tashladi (50 000 "katta" emas, teng). Qolgan uchta qatordan guruhlar yasaldi: Toshkent — 2, Samarqand — 1. HAVING faqat Toshkentni qoldirdi.

Ko'p uchraydigan xato

Agregatni WHERE ga yozish:

Noto'g'ri yondashuv
SELECT city, COUNT(*)
FROM orders
WHERE COUNT(*) >= 2
GROUP BY city;

PostgreSQL darhol xato beradi: aggregate functions are not allowed in WHERE. Sababi yuqoridagi tartibda — WHERE paytida hali sanaydigan guruh yo'q.

Teskari xato: hamma narsani HAVING ga yozish

Bu so'rov ishlaydi, lekin yomon odat:

Noto'g'ri yondashuv
SELECT city, COUNT(*)
FROM orders
GROUP BY city
HAVING city <> 'Buxoro';

Shahar bo'yicha shart guruhga emas, qatorga tegishli. Uni WHERE ga qo'ysangiz, keraksiz qatorlar guruhlashdan oldin tashlanadi va katta jadvalda so'rov sezilarli tezlashadi:

To'g'ri yechim
SELECT city, COUNT(*)
FROM orders
WHERE city <> 'Buxoro'
GROUP BY city;

Xulosa

  • WHERE — qatorlar uchun, guruhlashdan oldin; agregat ishlatib bo'lmaydi.
  • HAVING — guruhlar uchun, GROUP BY dan keyin; agregat bilan ishlaydi.
  • Shart agregatsiz bo'lsa, uni WHERE ga yozing — natija bir xil, lekin tezroq.

Endi o'zingiz yechib ko'ring

O'rganganingizni mustahkamlang — so'rovingiz brauzerda darhol tekshiriladi.