CodeShot

WHERE در مقابل HAVING

WHERE ردیف‌های خام جدول را پیش از هرگونه گروه‌بندی (GROUP BY) فیلتر می‌کند و نمی‌تواند به توابع تجمیعی مثل SUM یا COUNT ارجاع دهد؛ HAVING گروه‌های حاصل از GROUP BY را پس از تجمیع فیلتر می‌کند و دقیقاً برای شرط‌گذاری روی نتایج توابع تجمیعی ساخته شده است.

ویژگیWHEREHAVING
زمان اجرا در پردازش Queryقبل از GROUP BYبعد از GROUP BY
دسترسی به توابع تجمیعیخیربله (SUM، COUNT، AVG و...)
عملکردسریع‌تر (فیلتر زودهنگام)کندتر نسبی (بعد از تجمیع کل داده)
کاربرد رایجفیلتر ردیف‌های خامفیلتر گروه‌ها بر اساس تجمیع

کِی از WHERE استفاده کنیم؟

برای فیلتر کردن ردیف‌های تکی بر اساس مقادیر ستون‌ها پیش از هرگونه تجمیع (مثل "فقط سفارش‌های سال ۱۴۰۳")، از WHERE استفاده کنید — چون زودتر اجرا می‌شود و کارآمدتر است.

کِی از HAVING استفاده کنیم؟

برای فیلتر کردن بر اساس نتیجه یک تابع تجمیعی روی گروه‌ها (مثل "فقط مشتریانی که بیش از ۵ سفارش دارند")، از HAVING استفاده کنید چون WHERE به COUNT/SUM دسترسی ندارد.

مثال WHERE

SELECT CustomerId, OrderDate
FROM Orders
WHERE OrderDate >= '2024-03-21';  -- filters raw rows first

مثال HAVING

SELECT CustomerId, COUNT(*) AS OrderCount
FROM Orders
GROUP BY CustomerId
HAVING COUNT(*) > 5;  -- filters aggregated groups

اشتباه رایج

تلاش برای نوشتن WHERE COUNT(*) > 5 که با خطای SQL مواجه می‌شود چون توابع تجمیعی هنوز در مرحله WHERE محاسبه نشده‌اند؛ یا برعکس، استفاده غیرضروری از HAVING برای شرط‌های ساده روی ستون‌های غیرتجمیعی که باعث می‌شود موتور دیتابیس ابتدا همه ردیف‌ها را گروه‌بندی کند و سپس فیلتر بزند (کندتر از WHERE).

جمع‌بندی

فیلتر روی ستون‌های خام → WHERE (زودتر و سریع‌تر)؛ فیلتر روی نتیجه توابع تجمیعی → HAVING (بعد از GROUP BY).